Version 3.6.0-106.0.dev

Merge 7eef09cd6eccd60d66fc75a0435d2979385614d0 into dev
diff --git a/pkg/dart2wasm/lib/async.dart b/pkg/dart2wasm/lib/async.dart
index deeca32..55e4020 100644
--- a/pkg/dart2wasm/lib/async.dart
+++ b/pkg/dart2wasm/lib/async.dart
@@ -10,19 +10,78 @@
 import 'code_generator.dart';
 import 'state_machine.dart';
 
-class AsyncCodeGenerator extends StateMachineCodeGenerator {
+class AsyncCodeGenerator extends StateMachineEntryCodeGenerator {
   AsyncCodeGenerator(super.translator, super.function, super.reference);
 
   late final ClassInfo asyncSuspendStateInfo =
       translator.classInfo[translator.asyncSuspendStateClass]!;
 
-  // Note: These locals are only available in "inner" functions.
-  w.Local get _suspendStateLocal => function.locals[0];
-  w.Local get _awaitValueLocal => function.locals[1];
-  w.Local get _pendingExceptionLocal => function.locals[2];
-  w.Local get _pendingStackTraceLocal => function.locals[3];
+  @override
+  void generateOuter(
+      FunctionNode functionNode, Context? context, Source functionSource) {
+    final resumeFun = _defineInnerBodyFunction(functionNode);
 
-  w.FunctionBuilder _defineBodyFunction(FunctionNode functionNode) =>
+    // Outer (wrapper) function creates async state, calls the inner function
+    // (which runs until first suspension point, i.e. `await`), and returns the
+    // completer's future.
+
+    // (1) Create async state.
+
+    final asyncStateLocal =
+        b.addLocal(w.RefType(asyncSuspendStateInfo.struct, nullable: false));
+
+    // AsyncResumeFun _resume
+    b.global_get(translator.makeFunctionRef(resumeFun));
+
+    // WasmStructRef? _context
+    if (context != null) {
+      assert(!context.isEmpty);
+      b.local_get(context.currentLocal);
+    } else {
+      b.ref_null(w.HeapType.struct);
+    }
+
+    // _AsyncCompleter _completer
+    types.makeType(this, functionNode.emittedValueType!);
+    call(translator.makeAsyncCompleter.reference);
+
+    // Allocate `_AsyncSuspendState`
+    call(translator.newAsyncSuspendState.reference);
+    b.local_set(asyncStateLocal);
+
+    // (2) Call inner function.
+    //
+    // Note: the inner function does not throw, so we don't need a `try` block
+    // here.
+
+    b.local_get(asyncStateLocal);
+    b.ref_null(translator.topInfo.struct); // await value
+    b.ref_null(translator.topInfo.struct); // error value
+    b.ref_null(translator.stackTraceInfo.repr.struct); // stack trace
+    b.call(resumeFun);
+    b.drop(); // drop null
+
+    // (3) Return the completer's future.
+
+    b.local_get(asyncStateLocal);
+    final completerFutureGetterType = translator
+        .signatureForDirectCall(translator.completerFuture.getterReference);
+    b.struct_get(
+        asyncSuspendStateInfo.struct, FieldIndex.asyncSuspendStateCompleter);
+    translator.convertType(
+        b,
+        asyncSuspendStateInfo.struct.fields[5].type.unpacked,
+        completerFutureGetterType.inputs[0]);
+    call(translator.completerFuture.getterReference);
+    b.return_();
+    b.end();
+
+    AsyncStateMachineCodeGenerator(translator, resumeFun, reference,
+            functionNode, functionSource, closures)
+        .generate();
+  }
+
+  w.FunctionBuilder _defineInnerBodyFunction(FunctionNode functionNode) =>
       m.functions.define(
           m.types.defineFunction([
             asyncSuspendStateInfo.nonNullableType, // _AsyncSuspendState
@@ -37,6 +96,24 @@
             translator.topInfo.nullableType
           ]),
           "${function.functionName} inner");
+}
+
+class AsyncStateMachineCodeGenerator extends StateMachineCodeGenerator {
+  AsyncStateMachineCodeGenerator(
+      super.translator,
+      super.function,
+      super.reference,
+      super.functionNode,
+      super.functionSource,
+      super.closures);
+
+  late final ClassInfo asyncSuspendStateInfo =
+      translator.classInfo[translator.asyncSuspendStateClass]!;
+
+  w.Local get _suspendStateLocal => function.locals[0];
+  w.Local get _awaitValueLocal => function.locals[1];
+  w.Local get _pendingExceptionLocal => function.locals[2];
+  w.Local get _pendingStackTraceLocal => function.locals[3];
 
   @override
   void setSuspendStateCurrentException(void Function() emitValue) {
@@ -94,86 +171,9 @@
   }
 
   @override
-  void generateFunctions(FunctionNode functionNode, Context? context) {
-    final resumeFun = _defineBodyFunction(functionNode);
-
-    _generateOuter(functionNode, context, resumeFun);
-
-    // Forget about the outer function locals containing the type arguments,
-    // so accesses to the type arguments in the inner function will fetch them
-    // from the context.
-    typeLocals.clear();
-
-    _generateInner(functionNode, context, resumeFun);
-  }
-
-  void _generateOuter(
-      FunctionNode functionNode, Context? context, w.BaseFunction resumeFun) {
-    // Outer (wrapper) function creates async state, calls the inner function
-    // (which runs until first suspension point, i.e. `await`), and returns the
-    // completer's future.
-
-    // (1) Create async state.
-
-    final asyncStateLocal =
-        b.addLocal(w.RefType(asyncSuspendStateInfo.struct, nullable: false));
-
-    // AsyncResumeFun _resume
-    b.global_get(translator.makeFunctionRef(resumeFun));
-
-    // WasmStructRef? _context
-    if (context != null) {
-      assert(!context.isEmpty);
-      b.local_get(context.currentLocal);
-    } else {
-      b.ref_null(w.HeapType.struct);
-    }
-
-    // _AsyncCompleter _completer
-    types.makeType(this, functionNode.emittedValueType!);
-    call(translator.makeAsyncCompleter.reference);
-
-    // Allocate `_AsyncSuspendState`
-    call(translator.newAsyncSuspendState.reference);
-    b.local_set(asyncStateLocal);
-
-    // (2) Call inner function.
-    //
-    // Note: the inner function does not throw, so we don't need a `try` block
-    // here.
-
-    b.local_get(asyncStateLocal);
-    b.ref_null(translator.topInfo.struct); // await value
-    b.ref_null(translator.topInfo.struct); // error value
-    b.ref_null(translator.stackTraceInfo.repr.struct); // stack trace
-    b.call(resumeFun);
-    b.drop(); // drop null
-
-    // (3) Return the completer's future.
-
-    b.local_get(asyncStateLocal);
-    final completerFutureGetterType = translator
-        .signatureForDirectCall(translator.completerFuture.getterReference);
-    b.struct_get(
-        asyncSuspendStateInfo.struct, FieldIndex.asyncSuspendStateCompleter);
-    translator.convertType(
-        b,
-        asyncSuspendStateInfo.struct.fields[5].type.unpacked,
-        completerFutureGetterType.inputs[0]);
-    call(translator.completerFuture.getterReference);
-    b.end();
-  }
-
-  void _generateInner(FunctionNode functionNode, Context? context,
-      w.FunctionBuilder resumeFun) {
+  void generateInner(FunctionNode functionNode, Context? context) {
     // void Function(_AsyncSuspendState, Object?, Object?, StackTrace?)
 
-    // Set the current Wasm function for the code generator to the inner
-    // function of the `async`, which is to contain the body.
-    function = resumeFun;
-    b = resumeFun.body;
-    functionType = resumeFun.type;
-
     // Set up locals for contexts and `this`.
     thisLocal = null;
     Context? localContext = context;
diff --git a/pkg/dart2wasm/lib/code_generator.dart b/pkg/dart2wasm/lib/code_generator.dart
index 6d96df2..aa3bf24 100644
--- a/pkg/dart2wasm/lib/code_generator.dart
+++ b/pkg/dart2wasm/lib/code_generator.dart
@@ -40,8 +40,8 @@
     with ExpressionVisitor1DefaultMixin<w.ValueType, w.ValueType>
     implements InitializerVisitor<void>, StatementVisitor<void> {
   final Translator translator;
-  w.FunctionType functionType;
-  w.InstructionsBuilder b;
+  final w.FunctionType functionType;
+  final w.InstructionsBuilder b;
   final Reference reference;
   late final List<w.Local> paramLocals;
   final w.Label? returnLabel;
diff --git a/pkg/dart2wasm/lib/state_machine.dart b/pkg/dart2wasm/lib/state_machine.dart
index cc0d292..84b43af 100644
--- a/pkg/dart2wasm/lib/state_machine.dart
+++ b/pkg/dart2wasm/lib/state_machine.dart
@@ -563,18 +563,74 @@
   CatchVariables._(this.exception, this.stackTrace);
 }
 
+abstract class StateMachineEntryCodeGenerator extends CodeGenerator {
+  final w.FunctionBuilder function;
+
+  StateMachineEntryCodeGenerator(
+      Translator translator, this.function, Reference reference)
+      : super(translator, function.type, function.body, reference,
+            paramLocals: function.locals.toList());
+
+  @override
+  void generate() {
+    final source = member.enclosingComponent!.uriToSource[member.fileUri]!;
+    closures = Closures(translator, member);
+    setSourceMapSource(source);
+    setSourceMapFileOffset(member.fileOffset);
+    setupParametersAndContexts(member.reference);
+    _generateBody(member.function!, source);
+  }
+
+  @override
+  void generateLambda(Lambda lambda, Closures closures) {
+    final source = lambda.functionNodeSource;
+    this.closures = closures;
+    setSourceMapSource(source);
+    setSourceMapFileOffset(lambda.functionNode.fileOffset);
+    setupLambdaParametersAndContexts(lambda);
+    _generateBody(lambda.functionNode, source);
+  }
+
+  void _generateBody(FunctionNode functionNode, Source functionSource) {
+    Context? context = closures.contexts[functionNode];
+    if (context != null && context.isEmpty) context = context.parent;
+
+    generateOuter(functionNode, context, functionSource);
+  }
+
+  /// Generate the outer function.
+  ///
+  /// - Outer function: the `async` or `sync*` function.
+  ///
+  ///   In case of `async` this function should return a future.
+  ///
+  ///   In case of `sync*`, this function should return an iterable.
+  ///
+  void generateOuter(
+      FunctionNode functionNode, Context? context, Source functionSource);
+}
+
 /// A [CodeGenerator] that compiles the function to a state machine based on
 /// the suspension points in the function (`await` expressions and `yield`
 /// statements).
 ///
 /// This is used to compile `async` and `sync*` functions.
 abstract class StateMachineCodeGenerator extends CodeGenerator {
-  w.FunctionBuilder function;
+  final w.FunctionBuilder function;
+  final FunctionNode functionNode;
+  final Source functionSource;
 
   StateMachineCodeGenerator(
-      Translator translator, this.function, Reference reference)
+      Translator translator,
+      this.function,
+      Reference reference,
+      this.functionNode,
+      this.functionSource,
+      Closures closures)
       : super(translator, function.type, function.body, reference,
-            paramLocals: function.locals.toList());
+            paramLocals: function.locals.toList()) {
+    this.closures = closures;
+  }
 
   /// Targets of the CFG, indexed by target index.
   late final List<StateTarget> targets;
@@ -612,23 +668,9 @@
 
   @override
   void generate() {
-    final source = member.enclosingComponent!.uriToSource[member.fileUri]!;
-    setSourceMapSource(source);
-    setSourceMapFileOffset(member.fileOffset);
-    closures = Closures(translator, member);
-    setupParametersAndContexts(member.reference);
-    _generateBodies(member.function!);
-  }
+    setSourceMapSource(functionSource);
+    setSourceMapFileOffset(functionNode.fileOffset);
 
-  @override
-  void generateLambda(Lambda lambda, Closures closures) {
-    this.closures = closures;
-    setSourceMapSource(lambda.functionNodeSource);
-    setupLambdaParametersAndContexts(lambda);
-    _generateBodies(lambda.functionNode);
-  }
-
-  void _generateBodies(FunctionNode functionNode) {
     // Number and categorize CFG targets.
     targets = _YieldFinder(translator.options.enableAsserts).find(functionNode);
     for (final target in targets) {
@@ -647,7 +689,14 @@
     Context? context = closures.contexts[functionNode];
     if (context != null && context.isEmpty) context = context.parent;
 
-    generateFunctions(functionNode, context);
+    generateInner(functionNode, context);
+  }
+
+  @override
+  void generateLambda(Lambda lambda, Closures closures) {
+    // This is only invoked for the actual async/async*/sync* code generator and
+    // not for the (inner) state machine code generator.
+    throw UnsupportedError('This should not be reachable');
   }
 
   /// Store the exception value emitted by [emitValue] in suspension state.
@@ -679,23 +728,10 @@
   /// iteration by returning `false`.
   void emitReturn(void Function() emitValue);
 
-  /// Generate the outer and inner functions.
-  ///
-  /// - Outer function: the `async` or `sync*` function.
-  ///
-  ///   In case of `async` this function should return a future.
-  ///
-  ///   In case of `sync*`, this function should return an iterable.
-  ///
-  ///   Note that when generating the outer function we can't use the
-  ///   [StateMachineCodeGenerator] methods, as the outer functions are not the
-  ///   state machines used to implement suspension and resumption.
+  /// Generate the inner functions.
   ///
   /// - Inner function: the function that will be called for resumption.
-  ///
-  ///   [StateMachineCodeGenerator] methods (visitors etc.) are for generating
-  ///   this function.
-  void generateFunctions(FunctionNode functionNode, Context? context);
+  void generateInner(FunctionNode functionNode, Context? context);
 
   void emitTargetLabel(StateTarget target) {
     currentTargetIndex++;
diff --git a/pkg/dart2wasm/lib/sync_star.dart b/pkg/dart2wasm/lib/sync_star.dart
index 38ff310..9718a48 100644
--- a/pkg/dart2wasm/lib/sync_star.dart
+++ b/pkg/dart2wasm/lib/sync_star.dart
@@ -10,6 +10,57 @@
 import 'code_generator.dart';
 import 'state_machine.dart';
 
+class SyncStarCodeGenerator extends StateMachineEntryCodeGenerator {
+  SyncStarCodeGenerator(super.translator, super.function, super.reference);
+
+  late final ClassInfo suspendStateInfo =
+      translator.classInfo[translator.suspendStateClass]!;
+
+  late final ClassInfo syncStarIterableInfo =
+      translator.classInfo[translator.syncStarIterableClass]!;
+
+  @override
+  void generateOuter(
+      FunctionNode functionNode, Context? context, Source functionSource) {
+    final resumeFun = _defineInnerBodyFunction(functionNode);
+
+    // Instantiate a [_SyncStarIterable] containing the context and resume
+    // function for this `sync*` function.
+    DartType elementType = functionNode.emittedValueType!;
+    translator.functions.recordClassAllocation(syncStarIterableInfo.classId);
+    b.i32_const(syncStarIterableInfo.classId);
+    b.i32_const(initialIdentityHash);
+    types.makeType(this, elementType);
+    if (context != null) {
+      assert(!context.isEmpty);
+      b.local_get(context.currentLocal);
+    } else {
+      b.ref_null(w.HeapType.struct);
+    }
+    b.global_get(translator.makeFunctionRef(resumeFun));
+    b.struct_new(syncStarIterableInfo.struct);
+    b.return_();
+    b.end();
+
+    SyncStarStateMachineCodeGenerator(translator, resumeFun, reference,
+            functionNode, functionSource, closures)
+        .generate();
+  }
+
+  w.FunctionBuilder _defineInnerBodyFunction(FunctionNode functionNode) =>
+      m.functions.define(
+          m.types.defineFunction([
+            suspendStateInfo.nonNullableType, // _SuspendState
+            translator.topInfo.nullableType, // Object?, error value
+            translator.stackTraceInfo.repr
+                .nullableType // StackTrace?, error stack trace
+          ], const [
+            // bool for whether the generator has more to do
+            w.NumType.i32
+          ]),
+          "${function.functionName} inner");
+}
+
 /// A specialized code generator for generating code for `sync*` functions.
 ///
 /// This will create an "outer" function which is a small function that just
@@ -25,8 +76,14 @@
 /// Local state is preserved via the closure contexts, which will implicitly
 /// capture all local variables in a `sync*` function even if they are not
 /// captured by any lambdas.
-class SyncStarCodeGenerator extends StateMachineCodeGenerator {
-  SyncStarCodeGenerator(super.translator, super.function, super.reference);
+class SyncStarStateMachineCodeGenerator extends StateMachineCodeGenerator {
+  SyncStarStateMachineCodeGenerator(
+      super.translator,
+      super.function,
+      super.reference,
+      super.functionNode,
+      super.functionSource,
+      super.closures);
 
   late final ClassInfo suspendStateInfo =
       translator.classInfo[translator.suspendStateClass]!;
@@ -42,19 +99,6 @@
   w.Local get _pendingExceptionLocal => function.locals[1];
   w.Local get _pendingStackTraceLocal => function.locals[2];
 
-  w.FunctionBuilder _defineBodyFunction(FunctionNode functionNode) =>
-      m.functions.define(
-          m.types.defineFunction([
-            suspendStateInfo.nonNullableType, // _SuspendState
-            translator.topInfo.nullableType, // Object?, error value
-            translator.stackTraceInfo.repr
-                .nullableType // StackTrace?, error stack trace
-          ], const [
-            // bool for whether the generator has more to do
-            w.NumType.i32
-          ]),
-          "${function.functionName} inner");
-
   @override
   void setSuspendStateCurrentException(void Function() emitValue) {
     b.local_get(_suspendStateLocal);
@@ -104,47 +148,7 @@
   }
 
   @override
-  void generateFunctions(FunctionNode functionNode, Context? context) {
-    final resumeFun = _defineBodyFunction(functionNode);
-
-    _generateOuter(functionNode, context, resumeFun);
-
-    // Forget about the outer function locals containing the type arguments,
-    // so accesses to the type arguments in the inner function will fetch them
-    // from the context.
-    typeLocals.clear();
-
-    _generateInner(functionNode, context, resumeFun);
-  }
-
-  void _generateOuter(
-      FunctionNode functionNode, Context? context, w.BaseFunction resumeFun) {
-    // Instantiate a [_SyncStarIterable] containing the context and resume
-    // function for this `sync*` function.
-    DartType elementType = functionNode.emittedValueType!;
-    translator.functions.recordClassAllocation(syncStarIterableInfo.classId);
-    b.i32_const(syncStarIterableInfo.classId);
-    b.i32_const(initialIdentityHash);
-    types.makeType(this, elementType);
-    if (context != null) {
-      assert(!context.isEmpty);
-      b.local_get(context.currentLocal);
-    } else {
-      b.ref_null(w.HeapType.struct);
-    }
-    b.global_get(translator.makeFunctionRef(resumeFun));
-    b.struct_new(syncStarIterableInfo.struct);
-    b.end();
-  }
-
-  void _generateInner(FunctionNode functionNode, Context? context,
-      w.FunctionBuilder resumeFun) {
-    // Set the current Wasm function for the code generator to the inner
-    // function of the `sync*`, which is to contain the body.
-    function = resumeFun;
-    b = resumeFun.body;
-    functionType = resumeFun.type;
-
+  void generateInner(FunctionNode functionNode, Context? context) {
     // Set up locals for contexts and `this`.
     thisLocal = null;
     Context? localContext = context;
@@ -197,6 +201,7 @@
     emitReturn(() {});
     b.end(); // masterLoop
 
+    b.return_();
     b.end(); // inner function
   }
 
diff --git a/pkg/dds/CHANGELOG.md b/pkg/dds/CHANGELOG.md
index 499429d..cd0d884 100644
--- a/pkg/dds/CHANGELOG.md
+++ b/pkg/dds/CHANGELOG.md
@@ -1,6 +1,7 @@
 # 4.2.5
 - Fixed DevTools URI not including a trailing '/' before the query parameters, which could prevent DevTools from loading properly.
 - [DAP] Fixed an issue where format specifiers and `format.hex` in `variablesRequest` would not apply to values from lists such as `Uint8List` from `dart:typed_data`.
+- Added `package:dds/dds_launcher.dart`, a library which can be used to launch DDS instances using `dart development-service`.
 
 # 4.2.4+1
 - Added missing type to `Event` in `postEvent`.
diff --git a/pkg/dds/lib/dds.dart b/pkg/dds/lib/dds.dart
index 8b22313..7a6ed14 100644
--- a/pkg/dds/lib/dds.dart
+++ b/pkg/dds/lib/dds.dart
@@ -169,6 +169,8 @@
   static const String protocolVersion = '2.0';
 }
 
+/// Thrown by DDS during initialization failures, unexpected connection issues,
+/// and when attempting to spawn DDS when an existing DDS instance exists.
 class DartDevelopmentServiceException implements Exception {
   /// Set when `DartDeveloperService.startDartDevelopmentService` is called and
   /// the target VM service already has a Dart Developer Service instance
@@ -182,6 +184,33 @@
   /// Set when a connection error has occurred after startup.
   static const int connectionError = 3;
 
+  factory DartDevelopmentServiceException.fromJson(Map<String, Object?> json) {
+    if (json
+        case {
+          'error_code': final int errorCode,
+          'message': final String message,
+          'uri': final String? uri
+        }) {
+      return switch (errorCode) {
+        existingDdsInstanceError =>
+          DartDevelopmentServiceException.existingDdsInstance(
+            message,
+            ddsUri: Uri.parse(uri!),
+          ),
+        failedToStartError => DartDevelopmentServiceException.failedToStart(),
+        connectionError =>
+          DartDevelopmentServiceException.connectionIssue(message),
+        _ => throw StateError(
+            'Invalid DartDevelopmentServiceException error_code: $errorCode',
+          ),
+      };
+    }
+    throw StateError('Invalid DartDevelopmentServiceException JSON: $json');
+  }
+
+  /// Thrown when `DartDeveloperService.startDartDevelopmentService` is called
+  /// and the target VM service already has a Dart Developer Service instance
+  /// connected.
   factory DartDevelopmentServiceException.existingDdsInstance(
     String message, {
     Uri? ddsUri,
@@ -192,11 +221,14 @@
     );
   }
 
+  /// Thrown when the connection to the remote VM service terminates unexpectedly
+  /// during Dart Development Service startup.
   factory DartDevelopmentServiceException.failedToStart() {
     return DartDevelopmentServiceException._(
         failedToStartError, 'Failed to start Dart Development Service');
   }
 
+  /// Thrown when a connection error has occurred after startup.
   factory DartDevelopmentServiceException.connectionIssue(String message) {
     return DartDevelopmentServiceException._(connectionError, message);
   }
@@ -215,6 +247,7 @@
   final String message;
 }
 
+/// Thrown when attempting to start a new DDS instance when one already exists.
 class ExistingDartDevelopmentServiceException
     extends DartDevelopmentServiceException {
   ExistingDartDevelopmentServiceException._(
diff --git a/pkg/dds/lib/dds_launcher.dart b/pkg/dds/lib/dds_launcher.dart
new file mode 100644
index 0000000..2e8ad80
--- /dev/null
+++ b/pkg/dds/lib/dds_launcher.dart
@@ -0,0 +1,198 @@
+// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+import 'dds.dart' hide DartDevelopmentService;
+import 'src/arg_parser.dart';
+import 'src/dds_impl.dart';
+
+/// Spawns a Dart Development Service instance which will communicate with a
+/// VM service. Requires the target VM service to have no other connected
+/// clients.
+///
+/// [remoteVmServiceUri] is the address of the VM service that this
+/// development service will communicate with.
+///
+/// If provided, [serviceUri] will determine the address and port of the
+/// spawned Dart Development Service.
+///
+/// [enableAuthCodes] controls whether or not an authentication code must
+/// be provided by clients when communicating with this instance of
+/// DDS. Authentication codes take the form of a base64
+/// encoded string provided as the first element of the DDS path and is meant
+/// to make it more difficult for unintended clients to connect to this
+/// service. Authentication codes are enabled by default.
+///
+/// If [serveDevTools] is enabled, DDS will serve a DevTools instance and act
+/// as a DevTools Server. If not specified, [devToolsServerAddress] is ignored.
+///
+/// If provided, DDS will redirect DevTools requests to an existing DevTools
+/// server hosted at [devToolsServerAddress]. Ignored if [serveDevTools] is not
+/// true.
+///
+/// If [enableServicePortFallback] is enabled, DDS will attempt to bind to any
+/// available port if the specified port is unavailable.
+///
+/// If set, the set of [cachedUserTags] will be used to determine which CPU
+/// samples should be cached by DDS.
+///
+/// If provided, [dartExecutable] is the path to the 'dart' executable that
+/// should be used to spawn the DDS instance. By default, `Platform.executable`
+/// is used.
+class DartDevelopmentServiceLauncher {
+  static Future<DartDevelopmentServiceLauncher> start({
+    required Uri remoteVmServiceUri,
+    Uri? serviceUri,
+    bool enableAuthCodes = true,
+    bool serveDevTools = false,
+    Uri? devToolsServerAddress,
+    bool enableServicePortFallback = false,
+    List<String> cachedUserTags = const <String>[],
+    String? dartExecutable,
+  }) async {
+    final process = await Process.start(
+      dartExecutable ?? Platform.executable,
+      <String>[
+        'development-service',
+        '--${DartDevelopmentServiceOptions.vmServiceUriOption}=$remoteVmServiceUri',
+        if (serviceUri != null) ...<String>[
+          '--${DartDevelopmentServiceOptions.bindAddressOption}=${serviceUri.host}',
+          '--${DartDevelopmentServiceOptions.bindPortOption}=${serviceUri.port}',
+        ],
+        if (!enableAuthCodes)
+          '--${DartDevelopmentServiceOptions.disableServiceAuthCodesFlag}',
+        if (serveDevTools)
+          '--${DartDevelopmentServiceOptions.serveDevToolsFlag}',
+        if (devToolsServerAddress != null)
+          '--${DartDevelopmentServiceOptions.devToolsServerAddressOption}=$devToolsServerAddress',
+        if (enableServicePortFallback)
+          '--${DartDevelopmentServiceOptions.enableServicePortFallbackFlag}',
+        for (final String tag in cachedUserTags)
+          '--${DartDevelopmentServiceOptions.cachedUserTagsOption}=$tag',
+      ],
+    );
+    final completer = Completer<DartDevelopmentServiceLauncher>();
+    late StreamSubscription<Object?> stderrSub;
+    stderrSub = process.stderr
+        .transform(utf8.decoder)
+        .transform(json.decoder)
+        .listen((Object? result) {
+      if (result
+          case {
+            'state': 'started',
+            'ddsUri': final String ddsUriStr,
+          }) {
+        final ddsUri = Uri.parse(ddsUriStr);
+        final devToolsUriStr = result['devToolsUri'] as String?;
+        final devToolsUri =
+            devToolsUriStr == null ? null : Uri.parse(devToolsUriStr);
+        final dtdUriStr =
+            (result['dtd'] as Map<String, Object?>?)?['uri'] as String?;
+        final dtdUri = dtdUriStr == null ? null : Uri.parse(dtdUriStr);
+
+        completer.complete(
+          DartDevelopmentServiceLauncher._(
+            process: process,
+            uri: ddsUri,
+            devToolsUri: devToolsUri,
+            dtdUri: dtdUri,
+          ),
+        );
+      } else if (result
+          case {
+            'state': 'error',
+            'error': final String error,
+          }) {
+        final Map<String, Object?>? exceptionDetails =
+            result['ddsExceptionDetails'] as Map<String, Object?>?;
+        completer.completeError(
+          exceptionDetails != null
+              ? DartDevelopmentServiceException.fromJson(exceptionDetails)
+              : StateError(error),
+        );
+      } else {
+        throw StateError('Unexpected result from DDS: $result');
+      }
+      stderrSub.cancel();
+    });
+    return completer.future;
+  }
+
+  DartDevelopmentServiceLauncher._({
+    required Process process,
+    required this.uri,
+    required this.devToolsUri,
+    required this.dtdUri,
+  }) : _ddsInstance = process;
+
+  final Process _ddsInstance;
+
+  /// The [Uri] VM service clients can use to communicate with this
+  /// DDS instance via HTTP.
+  final Uri uri;
+
+  /// The HTTP [Uri] of the hosted DevTools instance.
+  ///
+  /// Returns `null` if DevTools is not running.
+  final Uri? devToolsUri;
+
+  /// The [Uri] of the Dart Tooling Daemon instance that is hosted by DevTools.
+  ///
+  /// This will be null if DTD was not started by the DevTools server. For
+  /// example, it may have been started by an IDE.
+  final Uri? dtdUri;
+
+  /// The [Uri] VM service clients can use to communicate with this
+  /// DDS instance via server-sent events (SSE).
+  Uri get sseUri => _toSse(uri)!;
+
+  /// The [Uri] VM service clients can use to communicate with this
+  /// DDS instance via a [WebSocket].
+  Uri get wsUri => _toWebSocket(uri)!;
+
+  List<String> _cleanupPathSegments(Uri uri) {
+    final pathSegments = <String>[];
+    if (uri.pathSegments.isNotEmpty) {
+      pathSegments.addAll(
+        uri.pathSegments.where(
+          // Strip out the empty string that appears at the end of path segments.
+          // Empty string elements will result in an extra '/' being added to the
+          // URI.
+          (s) => s.isNotEmpty,
+        ),
+      );
+    }
+    return pathSegments;
+  }
+
+  Uri? _toWebSocket(Uri? uri) {
+    if (uri == null) {
+      return null;
+    }
+    final pathSegments = _cleanupPathSegments(uri);
+    pathSegments.add('ws');
+    return uri.replace(scheme: 'ws', pathSegments: pathSegments);
+  }
+
+  Uri? _toSse(Uri? uri) {
+    if (uri == null) {
+      return null;
+    }
+    final pathSegments = _cleanupPathSegments(uri);
+    pathSegments.add(DartDevelopmentServiceImpl.kSseHandlerPath);
+    return uri.replace(scheme: 'sse', pathSegments: pathSegments);
+  }
+
+  /// Completes when the DDS instance has shutdown.
+  Future<void> get done => _ddsInstance.exitCode;
+
+  /// Shutdown the DDS instance.
+  Future<void> shutdown() {
+    _ddsInstance.kill();
+    return _ddsInstance.exitCode;
+  }
+}
diff --git a/pkg/dds/lib/src/dds_impl.dart b/pkg/dds/lib/src/dds_impl.dart
index 376855e..69dcfd4 100644
--- a/pkg/dds/lib/src/dds_impl.dart
+++ b/pkg/dds/lib/src/dds_impl.dart
@@ -347,8 +347,8 @@
   Handler _sseHandler() {
     final handler = SseHandler(
       authCodesEnabled
-          ? Uri.parse('/$authCode/$_kSseHandlerPath')
-          : Uri.parse('/$_kSseHandlerPath'),
+          ? Uri.parse('/$authCode/$kSseHandlerPath')
+          : Uri.parse('/$kSseHandlerPath'),
       keepAlive: sseKeepAlive,
     );
 
@@ -441,7 +441,7 @@
       return null;
     }
     final pathSegments = _cleanupPathSegments(uri);
-    pathSegments.add(_kSseHandlerPath);
+    pathSegments.add(kSseHandlerPath);
     return uri.replace(scheme: 'sse', pathSegments: pathSegments);
   }
 
@@ -552,7 +552,7 @@
   StreamManager get streamManager => _streamManager;
   late StreamManager _streamManager;
 
-  static const _kSseHandlerPath = '\$debugHandler';
+  static const kSseHandlerPath = '\$debugHandler';
 
   late json_rpc.Peer vmServiceClient;
   late WebSocketChannel _vmServiceSocket;
diff --git a/pkg/dds/test/launcher_smoke_test.dart b/pkg/dds/test/launcher_smoke_test.dart
new file mode 100644
index 0000000..80fc54b
--- /dev/null
+++ b/pkg/dds/test/launcher_smoke_test.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2024, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:dds/dds_launcher.dart';
+import 'package:test/test.dart';
+import 'package:vm_service/vm_service_io.dart';
+
+import 'common/test_helper.dart';
+
+void main() {
+  group('DDS', () {
+    late Process process;
+    late DartDevelopmentServiceLauncher dds;
+
+    setUp(() async {
+      process = await spawnDartProcess('smoke.dart');
+    });
+
+    tearDown(() async {
+      await dds.shutdown();
+      process.kill();
+    });
+
+    void createSmokeTest(bool useAuthCodes) {
+      test(
+        'Launcher Smoke Test with ${useAuthCodes ? "" : "no"} authentication codes',
+        () async {
+          dds = await DartDevelopmentServiceLauncher.start(
+            remoteVmServiceUri: remoteVmServiceUri,
+            enableAuthCodes: useAuthCodes,
+          );
+
+          // Ensure basic websocket requests are forwarded correctly to the VM service.
+          final service = await vmServiceConnectUri(dds.wsUri.toString());
+          final version = await service.getVersion();
+          expect(version.major! > 0, true);
+          expect(version.minor! >= 0, true);
+
+          expect(
+            dds.uri.pathSegments,
+            useAuthCodes ? isNotEmpty : isEmpty,
+          );
+
+          // Ensure we can still make requests of the VM service via HTTP.
+          HttpClient client = HttpClient();
+          final request = await client.getUrl(remoteVmServiceUri.replace(
+            pathSegments: [
+              if (remoteVmServiceUri.pathSegments.isNotEmpty)
+                remoteVmServiceUri.pathSegments.first,
+              'getVersion',
+            ],
+          ));
+          final response = await request.close();
+          final Map<String, dynamic> jsonResponse = (await response
+              .transform(utf8.decoder)
+              .transform(json.decoder)
+              .single) as Map<String, dynamic>;
+          expect(jsonResponse['result']['type'], 'Version');
+          expect(jsonResponse['result']['major'] > 0, true);
+          expect(jsonResponse['result']['minor'] >= 0, true);
+        },
+      );
+    }
+
+    createSmokeTest(true);
+    createSmokeTest(false);
+  });
+}
diff --git a/pkg/front_end/lib/src/base/scope.dart b/pkg/front_end/lib/src/base/scope.dart
index bb726bd..1aabf30 100644
--- a/pkg/front_end/lib/src/base/scope.dart
+++ b/pkg/front_end/lib/src/base/scope.dart
@@ -26,7 +26,6 @@
 import '../source/source_function_builder.dart';
 import '../source/source_library_builder.dart';
 import '../source/source_member_builder.dart';
-import '../util/helpers.dart' show DelayedActionPerformer;
 import 'messages.dart';
 import 'name_space.dart';
 import 'uri_offset.dart';
@@ -773,9 +772,7 @@
   ProcedureKind? get kind => null;
 
   @override
-  void buildOutlineExpressions(
-      ClassHierarchy classHierarchy,
-      List<DelayedActionPerformer> delayedActionPerformers,
+  void buildOutlineExpressions(ClassHierarchy classHierarchy,
       List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
     throw new UnsupportedError('$runtimeType.buildOutlineExpressions');
   }
diff --git a/pkg/front_end/lib/src/builder/formal_parameter_builder.dart b/pkg/front_end/lib/src/builder/formal_parameter_builder.dart
index 8128c30..9f7c620 100644
--- a/pkg/front_end/lib/src/builder/formal_parameter_builder.dart
+++ b/pkg/front_end/lib/src/builder/formal_parameter_builder.dart
@@ -23,7 +23,6 @@
 import '../source/source_field_builder.dart';
 import '../source/source_library_builder.dart';
 import '../source/type_parameter_scope_builder.dart';
-import '../util/helpers.dart' show DelayedActionPerformer;
 import 'builder.dart';
 import 'constructor_builder.dart';
 import 'declaration_builders.dart';
@@ -273,8 +272,7 @@
 
   /// Builds the default value from this [initializerToken] if this is a
   /// formal parameter on a const constructor or instance method.
-  void buildOutlineExpressions(SourceLibraryBuilder libraryBuilder,
-      List<DelayedActionPerformer> delayedActionPerformers) {
+  void buildOutlineExpressions(SourceLibraryBuilder libraryBuilder) {
     if (needsDefaultValuesBuiltAsOutlineExpressions) {
       if (initializerToken != null) {
         final DeclarationBuilder declarationBuilder =
@@ -296,9 +294,7 @@
             bodyBuilder, initializer, variable!.type, hasDeclaredInitializer);
         variable!.initializer = initializer..parent = variable;
         initializerWasInferred = true;
-        bodyBuilder.performBacklogComputations(
-            delayedActionPerformers: delayedActionPerformers,
-            allowFurtherDelays: false);
+        bodyBuilder.performBacklogComputations();
       } else if (kind.isOptional) {
         // As done by BodyBuilder.endFormalParameter.
         variable!.initializer = new NullLiteral()..parent = variable;
diff --git a/pkg/front_end/lib/src/builder/metadata_builder.dart b/pkg/front_end/lib/src/builder/metadata_builder.dart
index 2e7c2da..315e768 100644
--- a/pkg/front_end/lib/src/builder/metadata_builder.dart
+++ b/pkg/front_end/lib/src/builder/metadata_builder.dart
@@ -107,7 +107,7 @@
       // TODO(johnniwinther): Avoid potentially inferring annotations multiple
       // times.
       bodyBuilder.inferAnnotations(parent, parent.annotations);
-      bodyBuilder.performBacklogComputations(allowFurtherDelays: false);
+      bodyBuilder.performBacklogComputations();
       for (MapEntry<MetadataBuilder, int> entry
           in parsedAnnotationBuilders.entries) {
         MetadataBuilder annotationBuilder = entry.key;
diff --git a/pkg/front_end/lib/src/builder/type_variable_builder.dart b/pkg/front_end/lib/src/builder/type_variable_builder.dart
index 6c56ff7..65dc82c 100644
--- a/pkg/front_end/lib/src/builder/type_variable_builder.dart
+++ b/pkg/front_end/lib/src/builder/type_variable_builder.dart
@@ -401,7 +401,6 @@
       SourceLibraryBuilder libraryBuilder,
       BodyBuilderContext bodyBuilderContext,
       ClassHierarchy classHierarchy,
-      List<DelayedActionPerformer> delayedActionPerformers,
       LookupScope scope) {
     MetadataBuilder.buildAnnotations(parameter, metadata, bodyBuilderContext,
         libraryBuilder, fileUri!, scope);
diff --git a/pkg/front_end/lib/src/kernel/benchmarker.dart b/pkg/front_end/lib/src/kernel/benchmarker.dart
index 8f7af23..c1164de 100644
--- a/pkg/front_end/lib/src/kernel/benchmarker.dart
+++ b/pkg/front_end/lib/src/kernel/benchmarker.dart
@@ -189,6 +189,7 @@
   outline_buildClassHierarchyMembers,
   outline_computeHierarchy,
   outline_installTypedefTearOffs,
+  outline_performRedirectingFactoryInference,
   outline_performTopLevelInference,
   outline_checkOverrides,
   outline_checkAbstractMembers,
@@ -279,7 +280,6 @@
   inferRedirectingFactoryTypeArguments,
 
   buildOutlineExpressions,
-  delayedActionPerformer,
 
   computeMacroApplications_macroExecutorProvider,
   macroApplications_macroExecutorLoadMacro,
diff --git a/pkg/front_end/lib/src/kernel/body_builder.dart b/pkg/front_end/lib/src/kernel/body_builder.dart
index 81a3d1e..356a7a5 100644
--- a/pkg/front_end/lib/src/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/kernel/body_builder.dart
@@ -100,8 +100,8 @@
 import '../type_inference/type_inferrer.dart'
     show TypeInferrer, InferredFunctionBody;
 import '../type_inference/type_schema.dart' show UnknownType;
-import '../util/local_stack.dart';
 import '../util/helpers.dart';
+import '../util/local_stack.dart';
 import 'benchmarker.dart' show Benchmarker;
 import 'body_builder_context.dart';
 import 'collections.dart';
@@ -126,7 +126,7 @@
 }
 
 class BodyBuilder extends StackListenerImpl
-    implements ExpressionGeneratorHelper, DelayedActionPerformer {
+    implements ExpressionGeneratorHelper {
   @override
   final Forest forest;
 
@@ -246,89 +246,6 @@
   /// nominal correspondingly.
   bool _insideOfFormalParameterType = false;
 
-  /// True if the currently built part of the body is inside of a default value
-  /// of a formal parameter.
-  ///
-  /// Being inside of a default value is treated with regards to possible
-  /// nestedness of the default values. See the documentation on
-  /// [_defaultValueNestingLevel] for details.
-  bool get _insideOfFormalParameterDefaultValue {
-    return _defaultValueNestingLevel > 0;
-  }
-
-  /// True if the parser is between [beginMetadata] and [endMetadata].
-  bool _insideMetadataParsing = false;
-
-  /// Numeric nestedness of formal parameter default values.
-  ///
-  /// The value of 0 means that the currently built part is not within a default
-  /// value. Consider the following clarifying examples.
-  ///
-  ///   // `const Bar()` isn't within a default value.
-  ///   foo() => const Bar();
-  ///
-  ///   // `const Bar()` is at [_defaultValueNestingLevel] = 1.
-  ///   foo([dynamic x = const Bar()]) {}
-  ///
-  ///   // `const Bar()` is at [_defaultValueNestingLevel] = 2.
-  ///   // `const Baz()` is at [_defaultValueNestingLevel] = 1.
-  ///   foo([dynamic x = ([dynamic y = const Bar()]) => const Baz()]) {}
-  ///
-  ///  Since function expressions aren't const values, currently it's not
-  ///  possible to write a program with [_defaultValueNestingLevel] > 1 that
-  ///  doesn't contain a compile-time error. However, it's still necessary to
-  ///  track the nestedness level to avoid bad compiler states and compiler
-  ///  crashes.
-  int _defaultValueNestingLevel = 0;
-
-  /// Returns true if newly created aliased or redirecting invocations need
-  /// post-processing such as resolution or unaliasing.
-  ///
-  /// The need for the condition computed by the getter is due to some parts of
-  /// the AST being built twice. The first time they are built is during
-  /// outline expressions building. The second time they are built during the
-  /// function body building. However, they are fully processed only the first
-  /// time they are built, and the second time around they are discarded.
-  /// Additional complication arises due to some nodes, such as annotations,
-  /// being built only once. So we only need to add the nodes created for the
-  /// first time into the lists of nodes for post-processing.
-  ///
-  /// The invocations inside default values that need resolution or unaliasing
-  /// were already added to the post-processing lists during outline expression
-  /// building. Only those invocations that are built outside of the default
-  /// values or inside the default values that aren't built as outline
-  /// expressions need to be added during the second pass.
-  bool get _createdStaticInvocationsNeedPostProcessing {
-    return
-        // All invocations in outline building phase will be type-inferred, and
-        // they all should be added to the post-processing.
-        _context.inOutlineBuildingPhase ||
-
-            // Here we aren't in the outline mode, but rather in the
-            // body-building mode. If the current context has formal parameters
-            // and is a constructor context, their default values should be
-            // skipped because in the body-building mode they aren't passed
-            // through type inference.
-            (!_context.hasFormalParameters ||
-                    !_insideOfFormalParameterDefaultValue ||
-                    !_context.isConstructor) &&
-
-                // The invocations in the metadata should also be skipped in the
-                // body-building phase, since they aren't type-inferred. An
-                // exception here are the annotations within method bodies,
-                // field initializers, and on formal parameters.
-                !(_context.inMetadata ||
-                    _insideMetadataParsing &&
-                        !_inBody &&
-                        !inFormals &&
-                        !inFieldInitializer) &&
-
-                // Finally, the const fields in body-building phase aren't
-                // inferred and the invocations in them should be skipped during
-                // post-processing.
-                !_context.inConstFields;
-  }
-
   bool get inFunctionType =>
       _structuralParameterDepthLevel > 0 || _insideOfFormalParameterType;
 
@@ -346,10 +263,6 @@
 
   int functionNestingLevel = 0;
 
-  int _inBodyCount = 0;
-
-  bool get _inBody => _inBodyCount > 0;
-
   Statement? problemInLoopOrSwitch;
 
   LocalStack<LabelScope> _labelScopes;
@@ -371,41 +284,6 @@
   /// and where that was.
   Map<String, int>? initializedFields;
 
-  /// List of built redirecting factory invocations.  The targets of the
-  /// invocations are to be resolved in a separate step.
-  final List<FactoryConstructorInvocation> redirectingFactoryInvocations = [];
-
-  /// List of redirecting factory invocations delayed for resolution.
-  ///
-  /// A resolution of a redirecting factory invocation can be delayed because
-  /// the inference in the declaration of the redirecting factory isn't done
-  /// yet.
-  final List<FactoryConstructorInvocation>
-      delayedRedirectingFactoryInvocations = [];
-
-  /// List of built type aliased generative constructor invocations that
-  /// require unaliasing.
-  final List<TypeAliasedConstructorInvocation>
-      typeAliasedConstructorInvocations = [];
-
-  /// List of built type aliased factory constructor invocations that require
-  /// unaliasing.
-  final List<TypeAliasedFactoryInvocation> typeAliasedFactoryInvocations = [];
-
-  /// List of type aliased factory invocations delayed for resolution.
-  ///
-  /// A resolution of a type aliased factory invocation can be delayed because
-  /// the inference in the declaration of the target isn't done yet.
-  final List<TypeAliasedFactoryInvocation>
-      delayedTypeAliasedFactoryInvocations = [];
-
-  /// List of type aliased constructor invocations delayed for resolution.
-  ///
-  /// A resolution of a type aliased constructor invocation can be delayed
-  /// because the inference in the declaration of the target isn't done yet.
-  final List<TypeAliasedConstructorInvocation>
-      delayedTypeAliasedConstructorInvocations = [];
-
   /// Variables with metadata.  Their types need to be inferred late, for
   /// example, in [finishFunction].
   List<VariableDeclaration>? variablesWithMetadata;
@@ -538,9 +416,6 @@
   void enterLocalScope(LocalScope localScope) {
     _localScopes.push(localScope);
     _labelScopes.push(new LabelScopeImpl(_labelScope));
-    if (_localScope.kind == ScopeKind.functionBody) {
-      _inBodyCount++;
-    }
   }
 
   void createAndEnterLocalScope(
@@ -548,9 +423,6 @@
     _localScopes
         .push(_localScope.createNestedScope(debugName: debugName, kind: kind));
     _labelScopes.push(new LabelScopeImpl(_labelScope));
-    if (kind == ScopeKind.functionBody) {
-      _inBodyCount++;
-    }
   }
 
   void exitLocalScope({List<ScopeKind>? expectedScopeKinds}) {
@@ -571,9 +443,6 @@
         declaredInCurrentGuard = null;
       }
     }
-    if (_localScope.kind == ScopeKind.functionBody) {
-      _inBodyCount--;
-    }
     _labelScopes.pop();
     _localScopes.pop();
   }
@@ -939,7 +808,6 @@
     super.push(constantContext);
     constantContext = ConstantContext.inferred;
     assert(checkState(token, [ValueKinds.ConstantContext]));
-    _insideMetadataParsing = true;
   }
 
   @override
@@ -1017,7 +885,6 @@
       }
       constantContext = savedConstantContext;
     }
-    _insideMetadataParsing = false;
     assert(checkState(beginToken, [ValueKinds.Expression]));
   }
 
@@ -1101,21 +968,7 @@
         continue;
       }
       if (initializer != null) {
-        if (fieldBuilder.hasBodyBeenBuilt) {
-          // The initializer was already compiled (e.g., if it appear in the
-          // outline, like constant field initializers) so we do not need to
-          // perform type inference or transformations.
-
-          // If the body is already built and it's a type aliased constructor or
-          // factory invocation, they shouldn't be checked or resolved the
-          // second time, so they are removed from the corresponding lists.
-          if (initializer is TypeAliasedConstructorInvocation) {
-            typeAliasedConstructorInvocations.remove(initializer);
-          }
-          if (initializer is TypeAliasedFactoryInvocation) {
-            typeAliasedFactoryInvocations.remove(initializer);
-          }
-        } else {
+        if (!fieldBuilder.hasBodyBeenBuilt) {
           initializer = typeInferrer
               .inferFieldInitializer(this, fieldBuilder.builtType, initializer)
               .expression;
@@ -1143,7 +996,7 @@
     }
     pop(); // Annotations.
 
-    performBacklogComputations(allowFurtherDelays: false);
+    performBacklogComputations();
     assert(stack.length == 0);
   }
 
@@ -1152,40 +1005,13 @@
   ///
   /// Back logged computations include resolution of redirecting factory
   /// invocations and checking of typedef types.
-  ///
-  /// If the parameter [allowFurtherDelays] is set to `true`, the backlog
-  /// computations are allowed to be delayed one more time if they can't be
-  /// completed in the current invocation of [performBacklogComputations] and
-  /// have a chance to be completed during the next invocation. If
-  /// [allowFurtherDelays] is set to `false`, the backlog computations are
-  /// assumed to be final and the function throws an internal exception in case
-  /// if any of the computations can't be completed.
-  void performBacklogComputations(
-      {List<DelayedActionPerformer>? delayedActionPerformers,
-      required bool allowFurtherDelays}) {
+  void performBacklogComputations() {
     _finishVariableMetadata();
-    _unaliasTypeAliasedConstructorInvocations(
-        typeAliasedConstructorInvocations);
-    _unaliasTypeAliasedFactoryInvocations(typeAliasedFactoryInvocations);
-    _resolveRedirectingFactoryTargets(redirectingFactoryInvocations,
-        allowFurtherDelays: allowFurtherDelays);
     libraryBuilder.checkPendingBoundsChecks(typeEnvironment);
-    if (hasDelayedActions) {
-      assert(
-          delayedActionPerformers != null,
-          // Coverage-ignore(suite): Not run.
-          "Body builder has delayed actions that cannot be performed: "
-          "${[
-            ...delayedRedirectingFactoryInvocations,
-            ...delayedTypeAliasedFactoryInvocations,
-            ...delayedTypeAliasedConstructorInvocations,
-          ]}");
-      delayedActionPerformers?.add(this);
-    }
   }
 
   void finishRedirectingFactoryBody() {
-    performBacklogComputations(allowFurtherDelays: false);
+    performBacklogComputations();
   }
 
   @override
@@ -1497,7 +1323,7 @@
       _context.setBody(body);
     }
 
-    performBacklogComputations(allowFurtherDelays: false);
+    performBacklogComputations();
   }
 
   void checkAsyncReturnType(AsyncMarker asyncModifier, DartType returnType,
@@ -1615,7 +1441,8 @@
   /// [target], `.arguments` is [arguments], `.fileOffset` is [fileOffset],
   /// and `.isConst` is [isConst].
   /// Returns null if the invocation can't be resolved.
-  Expression? _resolveRedirectingFactoryTarget(
+  @override
+  Expression? resolveRedirectingFactoryTarget(
       Procedure target, Arguments arguments, int fileOffset, bool isConst) {
     Procedure initialTarget = target;
     Expression replacementNode;
@@ -1662,195 +1489,49 @@
     return replacementNode;
   }
 
-  /// If the parameter [allowFurtherDelays] is set to `true`, the resolution of
-  /// redirecting factories is allowed to be delayed one more time if it can't
-  /// be completed in the current invocation of
-  /// [_resolveRedirectingFactoryTargets] and has a chance to be completed
-  /// during the next invocation. If [allowFurtherDelays] is set to `false`,
-  /// the resolution of redirecting factories is assumed to be final and the
-  /// function throws an internal exception in case if any of the resolutions
-  /// can't be completed.
-  void _resolveRedirectingFactoryTargets(
-      List<FactoryConstructorInvocation> redirectingFactoryInvocations,
-      {required bool allowFurtherDelays}) {
-    List<FactoryConstructorInvocation> invocations =
-        redirectingFactoryInvocations.toList();
-    redirectingFactoryInvocations.clear();
-    for (FactoryConstructorInvocation invocation in invocations) {
-      // If the invocation was invalid, it or its parent has already been
-      // desugared into an exception throwing expression.  There is nothing to
-      // resolve anymore.  Note that in the case where the invocation's parent
-      // was invalid, type inference won't reach the invocation node and won't
-      // set its inferredType field.  If type inference is disabled, reach to
-      // the outermost parent to check if the node is a dead code.
-      if (invocation.parent == null) continue;
-      if (!invocation.hasBeenInferred) {
-        if (allowFurtherDelays) {
-          delayedRedirectingFactoryInvocations.add(invocation);
-        }
-        continue;
-      }
-      Expression? replacement = _resolveRedirectingFactoryTarget(
-          invocation.target,
-          invocation.arguments,
-          invocation.fileOffset,
-          invocation.isConst);
-      if (replacement == null) {
-        delayedRedirectingFactoryInvocations.add(invocation);
-      } else {
-        invocation.parent?.replaceChild(invocation, replacement);
-      }
-    }
-  }
-
-  void _unaliasTypeAliasedConstructorInvocations(
-      List<TypeAliasedConstructorInvocation>
-          typeAliasedConstructorInvocations) {
-    List<TypeAliasedConstructorInvocation> invocations = [
-      ...typeAliasedConstructorInvocations
-    ];
-    typeAliasedConstructorInvocations.clear();
-    for (TypeAliasedConstructorInvocation invocation in invocations) {
-      assert(
-          invocation.hasBeenInferred || isOrphaned(invocation),
-          // Coverage-ignore(suite): Not run.
-          "Node $invocation has not been inferred.");
-
-      Expression? replacement;
-      if (invocation.hasBeenInferred) {
-        bool inferred = !hasExplicitTypeArguments(invocation.arguments);
-        DartType aliasedType = new TypedefType(
-            invocation.typeAliasBuilder.typedef,
-            Nullability.nonNullable,
-            invocation.arguments.types);
-        libraryBuilder.checkBoundsInType(
-            aliasedType, typeEnvironment, uri, invocation.fileOffset,
-            allowSuperBounded: false, inferred: inferred);
-        DartType unaliasedType = aliasedType.unalias;
-        List<DartType>? invocationTypeArguments = null;
-        if (unaliasedType is InterfaceType) {
-          invocationTypeArguments = unaliasedType.typeArguments;
-        }
-        Arguments invocationArguments = forest.createArguments(
-            noLocation, invocation.arguments.positional,
-            types: invocationTypeArguments, named: invocation.arguments.named);
-        replacement = new ConstructorInvocation(
-            invocation.target, invocationArguments,
-            isConst: invocation.isConst);
-      }
-      if (replacement == null) {
-        delayedTypeAliasedConstructorInvocations.add(invocation);
-      } else {
-        invocation.parent?.replaceChild(invocation, replacement);
-      }
-    }
-    typeAliasedConstructorInvocations.clear();
-  }
-
-  void _unaliasTypeAliasedFactoryInvocations(
-      List<TypeAliasedFactoryInvocation> typeAliasedFactoryInvocations) {
-    List<TypeAliasedFactoryInvocation> invocations =
-        typeAliasedFactoryInvocations.toList();
-    typeAliasedFactoryInvocations.clear();
-    for (TypeAliasedFactoryInvocation invocation in invocations) {
-      assert(
-          invocation.hasBeenInferred || isOrphaned(invocation),
-          // Coverage-ignore(suite): Not run.
-          "Node $invocation has not been inferred.");
-
-      Expression? replacement;
-      if (invocation.hasBeenInferred) {
-        bool inferred = !hasExplicitTypeArguments(invocation.arguments);
-        DartType aliasedType = new TypedefType(
-            invocation.typeAliasBuilder.typedef,
-            Nullability.nonNullable,
-            invocation.arguments.types);
-        libraryBuilder.checkBoundsInType(
-            aliasedType, typeEnvironment, uri, invocation.fileOffset,
-            allowSuperBounded: false, inferred: inferred);
-        DartType unaliasedType = aliasedType.unalias;
-        List<DartType>? invocationTypeArguments = null;
-        if (unaliasedType is TypeDeclarationType) {
-          invocationTypeArguments = unaliasedType.typeArguments;
-        }
-        Arguments invocationArguments = forest.createArguments(
-            noLocation, invocation.arguments.positional,
-            types: invocationTypeArguments,
-            named: invocation.arguments.named,
-            hasExplicitTypeArguments:
-                hasExplicitTypeArguments(invocation.arguments));
-        replacement = _resolveRedirectingFactoryTarget(invocation.target,
-            invocationArguments, invocation.fileOffset, invocation.isConst);
-      }
-
-      if (replacement == null) {
-        delayedTypeAliasedFactoryInvocations.add(invocation);
-      } else {
-        invocation.parent?.replaceChild(invocation, replacement);
-      }
-    }
-    typeAliasedFactoryInvocations.clear();
-  }
-
-  /// Perform actions that were delayed
-  ///
-  /// An action can be delayed, for instance, because it depends on some
-  /// calculations in another library.  For example, a resolution of a
-  /// redirecting factory invocation depends on the type inference in the
-  /// redirecting factory.
   @override
-  void performDelayedActions({required bool allowFurtherDelays}) {
-    if (delayedRedirectingFactoryInvocations.isNotEmpty) {
-      _resolveRedirectingFactoryTargets(delayedRedirectingFactoryInvocations,
-          allowFurtherDelays: allowFurtherDelays);
-      if (delayedRedirectingFactoryInvocations.isNotEmpty) {
-        // Coverage-ignore-block(suite): Not run.
-        for (StaticInvocation invocation
-            in delayedRedirectingFactoryInvocations) {
-          internalProblem(
-              fasta.templateInternalProblemUnhandled.withArguments(
-                  invocation.target.name.text, 'performDelayedActions'),
-              invocation.fileOffset,
-              uri);
-        }
-      }
+  Expression unaliasSingleTypeAliasedConstructorInvocation(
+      TypeAliasedConstructorInvocation invocation) {
+    bool inferred = !hasExplicitTypeArguments(invocation.arguments);
+    DartType aliasedType = new TypedefType(invocation.typeAliasBuilder.typedef,
+        Nullability.nonNullable, invocation.arguments.types);
+    libraryBuilder.checkBoundsInType(
+        aliasedType, typeEnvironment, uri, invocation.fileOffset,
+        allowSuperBounded: false, inferred: inferred);
+    DartType unaliasedType = aliasedType.unalias;
+    List<DartType>? invocationTypeArguments = null;
+    if (unaliasedType is InterfaceType) {
+      invocationTypeArguments = unaliasedType.typeArguments;
     }
-    if (delayedTypeAliasedFactoryInvocations.isNotEmpty) {
-      _unaliasTypeAliasedFactoryInvocations(
-          delayedTypeAliasedFactoryInvocations);
-      if (delayedTypeAliasedFactoryInvocations.isNotEmpty) {
-        // Coverage-ignore-block(suite): Not run.
-        for (StaticInvocation invocation
-            in delayedTypeAliasedFactoryInvocations) {
-          internalProblem(
-              fasta.templateInternalProblemUnhandled.withArguments(
-                  invocation.target.name.text, 'performDelayedActions'),
-              invocation.fileOffset,
-              uri);
-        }
-      }
-    }
-    if (delayedTypeAliasedConstructorInvocations.isNotEmpty) {
-      _unaliasTypeAliasedConstructorInvocations(
-          delayedTypeAliasedConstructorInvocations);
-      if (delayedTypeAliasedConstructorInvocations.isNotEmpty) {
-        // Coverage-ignore-block(suite): Not run.
-        for (ConstructorInvocation invocation
-            in delayedTypeAliasedConstructorInvocations) {
-          internalProblem(
-              fasta.templateInternalProblemUnhandled.withArguments(
-                  invocation.target.name.text, 'performDelayedActions'),
-              invocation.fileOffset,
-              uri);
-        }
-      }
-    }
+    Arguments invocationArguments = forest.createArguments(
+        noLocation, invocation.arguments.positional,
+        types: invocationTypeArguments, named: invocation.arguments.named);
+    return new ConstructorInvocation(invocation.target, invocationArguments,
+        isConst: invocation.isConst);
   }
 
-  bool get hasDelayedActions {
-    return delayedRedirectingFactoryInvocations.isNotEmpty ||
-        delayedTypeAliasedFactoryInvocations.isNotEmpty ||
-        delayedTypeAliasedConstructorInvocations.isNotEmpty;
+  @override
+  Expression? unaliasSingleTypeAliasedFactoryInvocation(
+      TypeAliasedFactoryInvocation invocation) {
+    bool inferred = !hasExplicitTypeArguments(invocation.arguments);
+    DartType aliasedType = new TypedefType(invocation.typeAliasBuilder.typedef,
+        Nullability.nonNullable, invocation.arguments.types);
+    libraryBuilder.checkBoundsInType(
+        aliasedType, typeEnvironment, uri, invocation.fileOffset,
+        allowSuperBounded: false, inferred: inferred);
+    DartType unaliasedType = aliasedType.unalias;
+    List<DartType>? invocationTypeArguments = null;
+    if (unaliasedType is TypeDeclarationType) {
+      invocationTypeArguments = unaliasedType.typeArguments;
+    }
+    Arguments invocationArguments = forest.createArguments(
+        noLocation, invocation.arguments.positional,
+        types: invocationTypeArguments,
+        named: invocation.arguments.named,
+        hasExplicitTypeArguments:
+            hasExplicitTypeArguments(invocation.arguments));
+    return resolveRedirectingFactoryTarget(invocation.target,
+        invocationArguments, invocation.fileOffset, invocation.isConst);
   }
 
   void _finishVariableMetadata() {
@@ -1902,15 +1583,14 @@
       // Coverage-ignore-block(suite): Not run.
       temporaryParent = new ListLiteral(expressions);
     }
-    performBacklogComputations(allowFurtherDelays: false);
     // Coverage-ignore(suite): Not run.
+    performBacklogComputations();
     return temporaryParent != null ? temporaryParent.expressions : expressions;
   }
 
   // Coverage-ignore(suite): Not run.
   Expression parseSingleExpression(
       Parser parser, Token token, FunctionNode parameters) {
-    assert(redirectingFactoryInvocations.isEmpty);
     int fileOffset = offsetForToken(token);
     List<NominalVariableBuilder>? typeParameterBuilders;
     for (TypeParameter typeParameter in parameters.typeParameters) {
@@ -1988,7 +1668,7 @@
         "Previously implicit assumption about inferFunctionBody "
         "not returning anything different.");
 
-    performBacklogComputations(allowFurtherDelays: false);
+    performBacklogComputations();
 
     return fakeReturn.expression!;
   }
@@ -5764,7 +5444,6 @@
     super.push(constantContext);
     _insideOfFormalParameterType = false;
     constantContext = ConstantContext.required;
-    _defaultValueNestingLevel++;
   }
 
   @override
@@ -5773,7 +5452,6 @@
     Object? defaultValueExpression = pop();
     constantContext = pop() as ConstantContext;
     push(defaultValueExpression);
-    _defaultValueNestingLevel--;
   }
 
   @override
@@ -6253,17 +5931,12 @@
         libraryBuilder.checkBoundsInConstructorInvocation(
             node, typeEnvironment, uri);
       } else {
-        TypeAliasedConstructorInvocation typeAliasedConstructorInvocation =
-            node = new TypeAliasedConstructorInvocation(
-                typeAliasBuilder, target, arguments,
-                isConst: isConst)
-              ..fileOffset = charOffset;
+        node = new TypeAliasedConstructorInvocation(
+            typeAliasBuilder, target, arguments,
+            isConst: isConst)
+          ..fileOffset = charOffset;
         // No type arguments were passed, so we need not check bounds.
         assert(arguments.types.isEmpty);
-        if (_createdStaticInvocationsNeedPostProcessing) {
-          typeAliasedConstructorInvocations
-              .add(typeAliasedConstructorInvocation);
-        }
       }
       return node;
     } else {
@@ -6295,9 +5968,6 @@
           libraryBuilder.checkBoundsInFactoryInvocation(
               factoryConstructorInvocation, typeEnvironment, uri,
               inferred: !hasExplicitTypeArguments(arguments));
-          if (_createdStaticInvocationsNeedPostProcessing) {
-            redirectingFactoryInvocations.add(factoryConstructorInvocation);
-          }
           node = factoryConstructorInvocation;
         } else {
           TypeAliasedFactoryInvocation typeAliasedFactoryInvocation =
@@ -6307,9 +5977,6 @@
                 ..fileOffset = charOffset;
           // No type arguments were passed, so we need not check bounds.
           assert(arguments.types.isEmpty);
-          if (_createdStaticInvocationsNeedPostProcessing) {
-            typeAliasedFactoryInvocations.add(typeAliasedFactoryInvocation);
-          }
           node = typeAliasedFactoryInvocation;
         }
         return node;
@@ -10525,7 +10192,6 @@
           node.target, clone(node.arguments),
           isConst: node.isConst)
         ..hasBeenInferred = node.hasBeenInferred;
-      bodyBuilder.redirectingFactoryInvocations.add(result);
       return result;
     }
     // Coverage-ignore(suite): Not run.
@@ -10534,7 +10200,6 @@
           node.typeAliasBuilder, node.target, clone(node.arguments),
           isConst: node.isConst)
         ..hasBeenInferred = node.hasBeenInferred;
-      bodyBuilder.typeAliasedFactoryInvocations.add(result);
       return result;
     }
     // Coverage-ignore(suite): Not run.
@@ -10550,7 +10215,6 @@
               node.typeAliasBuilder, node.target, clone(node.arguments),
               isConst: node.isConst)
             ..hasBeenInferred = node.hasBeenInferred;
-      bodyBuilder.typeAliasedConstructorInvocations.add(result);
       return result;
     }
     return super.visitConstructorInvocation(node);
diff --git a/pkg/front_end/lib/src/kernel/kernel_target.dart b/pkg/front_end/lib/src/kernel/kernel_target.dart
index 747d9f1..526a03b 100644
--- a/pkg/front_end/lib/src/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/kernel/kernel_target.dart
@@ -616,6 +616,15 @@
 
       benchmarker
           // Coverage-ignore(suite): Not run.
+          ?.enterPhase(
+              BenchmarkPhases.outline_performRedirectingFactoryInference);
+      // TODO(johnniwinther): Add an interface for registering delayed actions.
+      List<DelayedDefaultValueCloner> delayedDefaultValueCloners = [];
+      loader.inferRedirectingFactories(
+          loader.hierarchy, delayedDefaultValueCloners);
+
+      benchmarker
+          // Coverage-ignore(suite): Not run.
           ?.enterPhase(BenchmarkPhases.outline_performTopLevelInference);
       loader.performTopLevelInference(sortedSourceClassBuilders);
 
@@ -637,8 +646,6 @@
       benchmarker
           // Coverage-ignore(suite): Not run.
           ?.enterPhase(BenchmarkPhases.outline_buildOutlineExpressions);
-      // TODO(johnniwinther): Add an interface for registering delayed actions.
-      List<DelayedDefaultValueCloner> delayedDefaultValueCloners = [];
       loader.buildOutlineExpressions(
           loader.hierarchy, delayedDefaultValueCloners);
       delayedDefaultValueCloners.forEach(registerDelayedDefaultValueCloner);
diff --git a/pkg/front_end/lib/src/source/source_builder_factory.dart b/pkg/front_end/lib/src/source/source_builder_factory.dart
index d02d5ad..0ca16da 100644
--- a/pkg/front_end/lib/src/source/source_builder_factory.dart
+++ b/pkg/front_end/lib/src/source/source_builder_factory.dart
@@ -1519,6 +1519,8 @@
           procedureNameScheme,
           nativeMethodName,
           redirectionTarget);
+      (_parent.redirectingFactoryBuilders ??= [])
+          .add(procedureBuilder as RedirectingFactoryBuilder);
     } else {
       procedureBuilder = new SourceFactoryBuilder(
           metadata,
diff --git a/pkg/front_end/lib/src/source/source_builder_mixins.dart b/pkg/front_end/lib/src/source/source_builder_mixins.dart
index defa998..8201a79 100644
--- a/pkg/front_end/lib/src/source/source_builder_mixins.dart
+++ b/pkg/front_end/lib/src/source/source_builder_mixins.dart
@@ -20,7 +20,6 @@
 import '../builder/type_builder.dart';
 import '../kernel/body_builder_context.dart';
 import '../kernel/kernel_helper.dart';
-import '../util/helpers.dart';
 import 'source_constructor_builder.dart';
 import 'source_field_builder.dart';
 import 'source_library_builder.dart';
@@ -159,9 +158,7 @@
       required bool inMetadata,
       required bool inConstFields});
 
-  void buildOutlineExpressions(
-      ClassHierarchy classHierarchy,
-      List<DelayedActionPerformer> delayedActionPerformers,
+  void buildOutlineExpressions(ClassHierarchy classHierarchy,
       List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
     MetadataBuilder.buildAnnotations(
         annotatable,
@@ -182,7 +179,6 @@
                 inMetadata: true,
                 inConstFields: false),
             classHierarchy,
-            delayedActionPerformers,
             typeParameterScope);
       }
     }
@@ -190,8 +186,8 @@
     Iterator<SourceMemberBuilder> iterator = nameSpace.filteredIterator(
         parent: this, includeDuplicates: false, includeAugmentations: true);
     while (iterator.moveNext()) {
-      iterator.current.buildOutlineExpressions(
-          classHierarchy, delayedActionPerformers, delayedDefaultValueCloners);
+      iterator.current
+          .buildOutlineExpressions(classHierarchy, delayedDefaultValueCloners);
     }
   }
 
diff --git a/pkg/front_end/lib/src/source/source_class_builder.dart b/pkg/front_end/lib/src/source/source_class_builder.dart
index f6598d5..d2b4cf6 100644
--- a/pkg/front_end/lib/src/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/source/source_class_builder.dart
@@ -44,7 +44,6 @@
 import '../kernel/kernel_helper.dart';
 import '../kernel/type_algorithms.dart' show computeTypeVariableBuilderVariance;
 import '../kernel/utils.dart' show compareProcedures;
-import '../util/helpers.dart';
 import 'class_declaration.dart';
 import 'source_builder_mixins.dart';
 import 'source_constructor_builder.dart';
@@ -383,14 +382,12 @@
         inConstFields: inConstFields);
   }
 
-  void buildOutlineExpressions(
-      ClassHierarchy classHierarchy,
-      List<DelayedActionPerformer> delayedActionPerformers,
+  void buildOutlineExpressions(ClassHierarchy classHierarchy,
       List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
     void build(Builder declaration) {
       SourceMemberBuilder member = declaration as SourceMemberBuilder;
       member.buildOutlineExpressions(
-          classHierarchy, delayedActionPerformers, delayedDefaultValueCloners);
+          classHierarchy, delayedDefaultValueCloners);
     }
 
     MetadataBuilder.buildAnnotations(
@@ -413,7 +410,6 @@
                 inMetadata: true,
                 inConstFields: false),
             classHierarchy,
-            delayedActionPerformers,
             typeParameterScope);
       }
     }
diff --git a/pkg/front_end/lib/src/source/source_constructor_builder.dart b/pkg/front_end/lib/src/source/source_constructor_builder.dart
index 4f5fd9d..2572203 100644
--- a/pkg/front_end/lib/src/source/source_constructor_builder.dart
+++ b/pkg/front_end/lib/src/source/source_constructor_builder.dart
@@ -45,7 +45,6 @@
         finishProcedureAugmentation;
 import '../type_inference/inference_results.dart';
 import '../type_inference/type_schema.dart';
-import '../util/helpers.dart' show DelayedActionPerformer;
 import 'constructor_declaration.dart';
 import 'name_scheme.dart';
 import 'source_class_builder.dart';
@@ -302,9 +301,7 @@
   }
 
   void _buildConstructorForOutline(
-      Token? beginInitializers,
-      List<DelayedActionPerformer> delayedActionPerformers,
-      LookupScope declarationScope) {
+      Token? beginInitializers, LookupScope declarationScope) {
     if (beginInitializers != null) {
       final LocalScope? formalParameterScope;
       if (isConst) {
@@ -328,11 +325,10 @@
       if (isConst) {
         bodyBuilder.constantContext = ConstantContext.required;
       }
+      inferFormalTypes(bodyBuilder.hierarchy);
       bodyBuilder.parseInitializers(beginInitializers,
           doFinishConstructor: isConst);
-      bodyBuilder.performBacklogComputations(
-          delayedActionPerformers: delayedActionPerformers,
-          allowFurtherDelays: false);
+      bodyBuilder.performBacklogComputations();
     }
   }
 
@@ -842,24 +838,20 @@
   bool _hasBuiltOutlines = false;
 
   @override
-  void buildOutlineExpressions(
-      ClassHierarchy classHierarchy,
-      List<DelayedActionPerformer> delayedActionPerformers,
+  void buildOutlineExpressions(ClassHierarchy classHierarchy,
       List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
     if (_hasBuiltOutlines) return;
     if (isConst && isAugmenting) {
       origin.buildOutlineExpressions(
-          classHierarchy, delayedActionPerformers, delayedDefaultValueCloners);
+          classHierarchy, delayedDefaultValueCloners);
     }
-    super.buildOutlineExpressions(
-        classHierarchy, delayedActionPerformers, delayedDefaultValueCloners);
+    super.buildOutlineExpressions(classHierarchy, delayedDefaultValueCloners);
 
     // For modular compilation purposes we need to include initializers
     // for const constructors into the outline. We also need to parse
     // initializers to infer types of the super-initializing parameters.
     if (isConst || _hasSuperInitializingFormals) {
-      _buildConstructorForOutline(
-          beginInitializers, delayedActionPerformers, classBuilder.scope);
+      _buildConstructorForOutline(beginInitializers, classBuilder.scope);
     }
     addSuperParameterDefaultValueCloners(delayedDefaultValueCloners);
     if (isConst && isAugmenting) {
@@ -1104,9 +1096,7 @@
   }
 
   @override
-  void buildOutlineExpressions(
-      ClassHierarchy classHierarchy,
-      List<DelayedActionPerformer> delayedActionPerformers,
+  void buildOutlineExpressions(ClassHierarchy classHierarchy,
       List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
     if (_immediatelyDefiningConstructor != null) {
       // Ensure that default value expressions have been created for [_origin].
@@ -1114,8 +1104,8 @@
       // values and initializers first.
       MemberBuilder origin = _immediatelyDefiningConstructor!;
       if (origin is SourceConstructorBuilder) {
-        origin.buildOutlineExpressions(classHierarchy, delayedActionPerformers,
-            delayedDefaultValueCloners);
+        origin.buildOutlineExpressions(
+            classHierarchy, delayedDefaultValueCloners);
       }
       addSuperParameterDefaultValueCloners(delayedDefaultValueCloners);
       _immediatelyDefiningConstructor = null;
@@ -1265,20 +1255,16 @@
   }
 
   @override
-  void buildOutlineExpressions(
-      ClassHierarchy classHierarchy,
-      List<DelayedActionPerformer> delayedActionPerformers,
+  void buildOutlineExpressions(ClassHierarchy classHierarchy,
       List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
-    super.buildOutlineExpressions(
-        classHierarchy, delayedActionPerformers, delayedDefaultValueCloners);
+    super.buildOutlineExpressions(classHierarchy, delayedDefaultValueCloners);
 
     if (isConst) {
       // For modular compilation purposes we need to include initializers
       // for const constructors into the outline.
       LookupScope typeParameterScope =
           computeTypeParameterScope(extensionTypeDeclarationBuilder.scope);
-      _buildConstructorForOutline(
-          beginInitializers, delayedActionPerformers, typeParameterScope);
+      _buildConstructorForOutline(beginInitializers, typeParameterScope);
       _buildBody();
     }
     beginInitializers = null;
diff --git a/pkg/front_end/lib/src/source/source_enum_builder.dart b/pkg/front_end/lib/src/source/source_enum_builder.dart
index 4540be2..2abf5d9 100644
--- a/pkg/front_end/lib/src/source/source_enum_builder.dart
+++ b/pkg/front_end/lib/src/source/source_enum_builder.dart
@@ -51,7 +51,6 @@
 import '../kernel/kernel_helper.dart';
 import '../type_inference/inference_results.dart';
 import '../type_inference/type_schema.dart';
-import '../util/helpers.dart';
 import 'name_scheme.dart';
 import 'source_class_builder.dart' show SourceClassBuilder;
 import 'source_constructor_builder.dart';
@@ -83,8 +82,6 @@
   final Set<SourceFieldBuilder> _builtElements =
       new Set<SourceFieldBuilder>.identity();
 
-  final List<DelayedActionPerformer> _delayedActionPerformers = [];
-
   SourceEnumBuilder.internal(
       List<MetadataBuilder>? metadata,
       String name,
@@ -702,9 +699,7 @@
         // redirecting factories can't be completed at this moment and
         // therefore should be delayed to another invocation of
         // [BodyBuilder.performBacklogComputations].
-        bodyBuilder.performBacklogComputations(
-            delayedActionPerformers: _delayedActionPerformers,
-            allowFurtherDelays: true);
+        bodyBuilder.performBacklogComputations();
 
         arguments.positional.insertAll(0, enumSyntheticArguments);
         arguments.argumentsOriginalOrder?.insertAll(0, enumSyntheticArguments);
@@ -778,9 +773,7 @@
   }
 
   @override
-  void buildOutlineExpressions(
-      ClassHierarchy classHierarchy,
-      List<DelayedActionPerformer> delayedActionPerformers,
+  void buildOutlineExpressions(ClassHierarchy classHierarchy,
       List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
     List<Expression> values = <Expression>[];
     if (enumConstantInfos != null) {
@@ -807,8 +800,6 @@
       elementBuilder.type.registerInferredType(
           buildElement(elementBuilder, classHierarchy.coreTypes));
     }
-    delayedActionPerformers.addAll(_delayedActionPerformers);
-    _delayedActionPerformers.clear();
 
     SourceProcedureBuilder toStringBuilder =
         firstMemberNamed("_enumToString") as SourceProcedureBuilder;
@@ -846,8 +837,7 @@
       ]));
     }
 
-    super.buildOutlineExpressions(
-        classHierarchy, delayedActionPerformers, delayedDefaultValueCloners);
+    super.buildOutlineExpressions(classHierarchy, delayedDefaultValueCloners);
   }
 }
 
diff --git a/pkg/front_end/lib/src/source/source_extension_type_declaration_builder.dart b/pkg/front_end/lib/src/source/source_extension_type_declaration_builder.dart
index 29dcd03..d892e59 100644
--- a/pkg/front_end/lib/src/source/source_extension_type_declaration_builder.dart
+++ b/pkg/front_end/lib/src/source/source_extension_type_declaration_builder.dart
@@ -29,7 +29,6 @@
 import '../kernel/kernel_helper.dart';
 import '../kernel/type_algorithms.dart';
 import '../type_inference/type_inference_engine.dart';
-import '../util/helpers.dart';
 import 'class_declaration.dart';
 import 'source_builder_mixins.dart';
 import 'source_constructor_builder.dart';
@@ -594,18 +593,15 @@
   }
 
   @override
-  void buildOutlineExpressions(
-      ClassHierarchy classHierarchy,
-      List<DelayedActionPerformer> delayedActionPerformers,
+  void buildOutlineExpressions(ClassHierarchy classHierarchy,
       List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
-    super.buildOutlineExpressions(
-        classHierarchy, delayedActionPerformers, delayedDefaultValueCloners);
+    super.buildOutlineExpressions(classHierarchy, delayedDefaultValueCloners);
 
     Iterator<SourceMemberBuilder> iterator = constructorScope.filteredIterator(
         parent: this, includeDuplicates: false, includeAugmentations: true);
     while (iterator.moveNext()) {
-      iterator.current.buildOutlineExpressions(
-          classHierarchy, delayedActionPerformers, delayedDefaultValueCloners);
+      iterator.current
+          .buildOutlineExpressions(classHierarchy, delayedDefaultValueCloners);
     }
   }
 
diff --git a/pkg/front_end/lib/src/source/source_factory_builder.dart b/pkg/front_end/lib/src/source/source_factory_builder.dart
index ff84d96..07f7370 100644
--- a/pkg/front_end/lib/src/source/source_factory_builder.dart
+++ b/pkg/front_end/lib/src/source/source_factory_builder.dart
@@ -24,6 +24,7 @@
 import '../builder/formal_parameter_builder.dart';
 import '../builder/function_builder.dart';
 import '../builder/metadata_builder.dart';
+import '../builder/omitted_type_builder.dart';
 import '../builder/type_builder.dart';
 import '../codes/cfe_codes.dart';
 import '../dill/dill_extension_type_member_builder.dart';
@@ -35,7 +36,6 @@
 import '../type_inference/inference_helper.dart';
 import '../type_inference/type_inferrer.dart';
 import '../type_inference/type_schema.dart';
-import '../util/helpers.dart';
 import 'name_scheme.dart';
 import 'redirecting_factory_body.dart';
 import 'source_class_builder.dart';
@@ -202,16 +202,13 @@
   bool _hasBuiltOutlines = false;
 
   @override
-  void buildOutlineExpressions(
-      ClassHierarchy classHierarchy,
-      List<DelayedActionPerformer> delayedActionPerformers,
+  void buildOutlineExpressions(ClassHierarchy classHierarchy,
       List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
     if (_hasBuiltOutlines) return;
     if (_delayedDefaultValueCloner != null) {
       delayedDefaultValueCloners.add(_delayedDefaultValueCloner!);
     }
-    super.buildOutlineExpressions(
-        classHierarchy, delayedActionPerformers, delayedDefaultValueCloners);
+    super.buildOutlineExpressions(classHierarchy, delayedDefaultValueCloners);
     _hasBuiltOutlines = true;
   }
 
@@ -487,20 +484,21 @@
   bool _hasBuiltOutlines = false;
 
   @override
-  void buildOutlineExpressions(
-      ClassHierarchy classHierarchy,
-      List<DelayedActionPerformer> delayedActionPerformers,
+  void buildOutlineExpressions(ClassHierarchy classHierarchy,
       List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
     if (_hasBuiltOutlines) return;
     if (isConst && isAugmenting) {
       origin.buildOutlineExpressions(
-          classHierarchy, delayedActionPerformers, delayedDefaultValueCloners);
+          classHierarchy, delayedDefaultValueCloners);
     }
-    super.buildOutlineExpressions(
-        classHierarchy, delayedActionPerformers, delayedDefaultValueCloners);
+    super.buildOutlineExpressions(classHierarchy, delayedDefaultValueCloners);
 
-    RedirectingFactoryTarget redirectingFactoryTarget =
-        _procedureInternal.function.redirectingFactoryTarget!;
+    RedirectingFactoryTarget? redirectingFactoryTarget =
+        _procedureInternal.function.redirectingFactoryTarget;
+    if (redirectingFactoryTarget == null) {
+      // The error is reported elsewhere.
+      return;
+    }
     List<DartType>? typeArguments = redirectingFactoryTarget.typeArguments;
     Member? target = redirectingFactoryTarget.target;
     if (typeArguments != null && typeArguments.any((t) => t is UnknownType)) {
@@ -519,8 +517,8 @@
       Builder? targetBuilder = redirectionTarget.target;
       if (targetBuilder is SourceMemberBuilder) {
         // Ensure that target has been built.
-        targetBuilder.buildOutlineExpressions(classHierarchy,
-            delayedActionPerformers, delayedDefaultValueCloners);
+        targetBuilder.buildOutlineExpressions(
+            classHierarchy, delayedDefaultValueCloners);
       }
       if (targetBuilder is FunctionBuilder) {
         target = targetBuilder.member;
@@ -532,6 +530,23 @@
         unhandled("${targetBuilder.runtimeType}", "buildOutlineExpressions",
             charOffset, fileUri);
       }
+
+      // Type arguments for the targets of redirecting factories can only be
+      // inferred if the formal parameters of the targets are inferred too.
+      // That may not be the case when the target's parameters are initializing
+      // parameters referring to fields with types that are to be inferred.
+      if (targetBuilder is SourceFunctionBuilderImpl) {
+        List<FormalParameterBuilder>? formals = targetBuilder.formals;
+        if (formals != null) {
+          for (FormalParameterBuilder formal in formals) {
+            TypeBuilder formalType = formal.type;
+            if (formalType is InferableTypeBuilder) {
+              formalType.inferType(classHierarchy);
+            }
+          }
+        }
+      }
+
       typeArguments = inferrer.inferRedirectingFactoryTypeArguments(
           helper,
           _procedureInternal.function.returnType,
diff --git a/pkg/front_end/lib/src/source/source_field_builder.dart b/pkg/front_end/lib/src/source/source_field_builder.dart
index 443b41e..d60b640 100644
--- a/pkg/front_end/lib/src/source/source_field_builder.dart
+++ b/pkg/front_end/lib/src/source/source_field_builder.dart
@@ -37,7 +37,6 @@
 import '../source/source_library_builder.dart' show SourceLibraryBuilder;
 import '../type_inference/type_inference_engine.dart'
     show IncludesTypeParametersNonCovariantly;
-import '../util/helpers.dart' show DelayedActionPerformer;
 import 'source_class_builder.dart';
 import 'source_extension_type_declaration_builder.dart';
 import 'source_member_builder.dart';
@@ -452,9 +451,7 @@
   Iterable<Annotatable> get annotatables => _fieldEncoding.annotatables;
 
   @override
-  void buildOutlineExpressions(
-      ClassHierarchy classHierarchy,
-      List<DelayedActionPerformer> delayedActionPerformers,
+  void buildOutlineExpressions(ClassHierarchy classHierarchy,
       List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
     for (Annotatable annotatable in annotatables) {
       MetadataBuilder.buildAnnotations(
@@ -495,9 +492,7 @@
               bodyBuilder.parseFieldInitializer(_constInitializerToken!))
           .expression;
       buildBody(classHierarchy.coreTypes, initializer);
-      bodyBuilder.performBacklogComputations(
-          delayedActionPerformers: delayedActionPerformers,
-          allowFurtherDelays: false);
+      bodyBuilder.performBacklogComputations();
     }
     _constInitializerToken = null;
   }
diff --git a/pkg/front_end/lib/src/source/source_function_builder.dart b/pkg/front_end/lib/src/source/source_function_builder.dart
index dac0725..3e5f9de 100644
--- a/pkg/front_end/lib/src/source/source_function_builder.dart
+++ b/pkg/front_end/lib/src/source/source_function_builder.dart
@@ -34,7 +34,6 @@
 import 'source_loader.dart' show SourceLoader;
 import '../type_inference/type_inference_engine.dart'
     show IncludesTypeParametersNonCovariantly;
-import '../util/helpers.dart' show DelayedActionPerformer;
 import 'source_builder_mixins.dart';
 import 'source_extension_type_declaration_builder.dart';
 import 'source_member_builder.dart';
@@ -482,9 +481,7 @@
   }
 
   @override
-  void buildOutlineExpressions(
-      ClassHierarchy classHierarchy,
-      List<DelayedActionPerformer> delayedActionPerformers,
+  void buildOutlineExpressions(ClassHierarchy classHierarchy,
       List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
     if (!hasBuiltOutlineExpressions) {
       DeclarationBuilder? classOrExtensionBuilder =
@@ -515,7 +512,6 @@
                   inMetadata: true,
                   inConstFields: false),
               classHierarchy,
-              delayedActionPerformers,
               computeTypeParameterScope(parentScope));
         }
       }
@@ -526,8 +522,7 @@
         // buildOutlineExpressions to clear initializerToken to prevent
         // consuming too much memory.
         for (FormalParameterBuilder formal in formals!) {
-          formal.buildOutlineExpressions(
-              libraryBuilder, delayedActionPerformers);
+          formal.buildOutlineExpressions(libraryBuilder);
         }
       }
       hasBuiltOutlineExpressions = true;
diff --git a/pkg/front_end/lib/src/source/source_library_builder.dart b/pkg/front_end/lib/src/source/source_library_builder.dart
index 58258b1..068f780 100644
--- a/pkg/front_end/lib/src/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/source/source_library_builder.dart
@@ -71,7 +71,6 @@
         exportNeverSentinel,
         toKernelCombinators,
         unserializableExportName;
-import '../util/helpers.dart';
 import 'builder_factory.dart';
 import 'class_declaration.dart';
 import 'name_scheme.dart';
@@ -189,6 +188,13 @@
   /// if [SourceLoader.computeFieldPromotability] hasn't been called.
   FieldNonPromotabilityInfo? fieldNonPromotabilityInfo;
 
+  /// Redirecting factory builders defined in the library. They should be
+  /// collected as they are built, so that we can build the outline expressions
+  /// in the right order.
+  ///
+  /// See [SourceLoader.buildOutlineExpressions] for details.
+  List<RedirectingFactoryBuilder>? redirectingFactoryBuilders;
+
   // TODO(johnniwinther): Remove this.
   final Map<String, List<Builder>>? augmentations;
 
@@ -1142,16 +1148,14 @@
         inConstFields: inConstFields);
   }
 
-  void buildOutlineExpressions(
-      ClassHierarchy classHierarchy,
-      List<DelayedDefaultValueCloner> delayedDefaultValueCloners,
-      List<DelayedActionPerformer> delayedActionPerformers) {
+  void buildOutlineExpressions(ClassHierarchy classHierarchy,
+      List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
     Iterable<SourceLibraryBuilder>? augmentationLibraries =
         this.augmentationLibraries;
     if (augmentationLibraries != null) {
       for (SourceLibraryBuilder augmentationLibrary in augmentationLibraries) {
-        augmentationLibrary.buildOutlineExpressions(classHierarchy,
-            delayedDefaultValueCloners, delayedActionPerformers);
+        augmentationLibrary.buildOutlineExpressions(
+            classHierarchy, delayedDefaultValueCloners);
       }
     }
 
@@ -1171,20 +1175,20 @@
     while (iterator.moveNext()) {
       Builder declaration = iterator.current;
       if (declaration is SourceClassBuilder) {
-        declaration.buildOutlineExpressions(classHierarchy,
-            delayedActionPerformers, delayedDefaultValueCloners);
+        declaration.buildOutlineExpressions(
+            classHierarchy, delayedDefaultValueCloners);
       } else if (declaration is SourceExtensionBuilder) {
-        declaration.buildOutlineExpressions(classHierarchy,
-            delayedActionPerformers, delayedDefaultValueCloners);
+        declaration.buildOutlineExpressions(
+            classHierarchy, delayedDefaultValueCloners);
       } else if (declaration is SourceExtensionTypeDeclarationBuilder) {
-        declaration.buildOutlineExpressions(classHierarchy,
-            delayedActionPerformers, delayedDefaultValueCloners);
+        declaration.buildOutlineExpressions(
+            classHierarchy, delayedDefaultValueCloners);
       } else if (declaration is SourceMemberBuilder) {
-        declaration.buildOutlineExpressions(classHierarchy,
-            delayedActionPerformers, delayedDefaultValueCloners);
+        declaration.buildOutlineExpressions(
+            classHierarchy, delayedDefaultValueCloners);
       } else if (declaration is SourceTypeAliasBuilder) {
-        declaration.buildOutlineExpressions(classHierarchy,
-            delayedActionPerformers, delayedDefaultValueCloners);
+        declaration.buildOutlineExpressions(
+            classHierarchy, delayedDefaultValueCloners);
       } else {
         assert(
             declaration is PrefixBuilder ||
diff --git a/pkg/front_end/lib/src/source/source_loader.dart b/pkg/front_end/lib/src/source/source_loader.dart
index 897c3e9..48d8dd8 100644
--- a/pkg/front_end/lib/src/source/source_loader.dart
+++ b/pkg/front_end/lib/src/source/source_loader.dart
@@ -78,7 +78,6 @@
 import '../macros/macro_injected_impl.dart' as injected;
 import '../type_inference/type_inference_engine.dart';
 import '../type_inference/type_inferrer.dart';
-import '../util/helpers.dart';
 import 'diet_listener.dart' show DietListener;
 import 'diet_parser.dart' show DietParser, useImplicitCreationExpressionInCfe;
 import 'name_scheme.dart';
@@ -88,6 +87,7 @@
 import 'source_constructor_builder.dart';
 import 'source_enum_builder.dart';
 import 'source_extension_type_declaration_builder.dart';
+import 'source_factory_builder.dart';
 import 'source_library_builder.dart'
     show
         ImplicitLanguageVersion,
@@ -2898,24 +2898,10 @@
 
   void buildOutlineExpressions(ClassHierarchy classHierarchy,
       List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
-    List<DelayedActionPerformer> delayedActionPerformers =
-        <DelayedActionPerformer>[];
     for (SourceLibraryBuilder library in sourceLibraryBuilders) {
       library.buildOutlineExpressions(
-          classHierarchy, delayedDefaultValueCloners, delayedActionPerformers);
+          classHierarchy, delayedDefaultValueCloners);
     }
-
-    target.benchmarker
-        // Coverage-ignore(suite): Not run.
-        ?.beginSubdivide(BenchmarkSubdivides.delayedActionPerformer);
-    for (DelayedActionPerformer delayedActionPerformer
-        in delayedActionPerformers) {
-      delayedActionPerformer.performDelayedActions(allowFurtherDelays: false);
-    }
-    target.benchmarker
-        // Coverage-ignore(suite): Not run.
-        ?.endSubdivide();
-    ticker.logMs("Build outline expressions");
   }
 
   void buildClassHierarchy(
@@ -2943,15 +2929,47 @@
         new TypeInferenceEngineImpl(instrumentation, target.benchmarker);
   }
 
-  void performTopLevelInference(List<SourceClassBuilder> sourceClasses) {
+  void inferRedirectingFactories(ClassHierarchy classHierarchy,
+      List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
+    /// Inferring redirecting factories partially overlaps with top-level
+    /// inference, since the formal parameters of the redirection targets should
+    /// be inferred, and they can be formal initializing parameters requiring
+    /// inference. [RedirectingFactoryBuilder.buildOutlineExpressions] can
+    /// invoke inference on those formal parameters. Therefore, the top-level
+    /// inference should be prepared before we can infer redirecting factories.
+
     /// The first phase of top level initializer inference, which consists of
     /// creating kernel objects for all fields and top level variables that
     /// might be subject to type inference, and records dependencies between
     /// them.
     typeInferenceEngine.prepareTopLevel(coreTypes, hierarchy);
     membersBuilder.computeTypes();
-    inferableTypes.inferTypes(typeInferenceEngine.hierarchyBuilder);
 
+    // TODO(cstefantsova): Put the redirecting factory inference into a separate
+    // step.
+
+    // Redirecting factory invocations can occur in outline expressions and
+    // should be processed before them. The outline expressions within
+    // redirecting factory invocations themselves are minimal, containing only
+    // the target and possibly some type arguments, and don't depend on other
+    // kinds of outline expressions themselves.
+    for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+      List<RedirectingFactoryBuilder>? redirectingFactoryBuilders =
+          library.redirectingFactoryBuilders;
+      if (redirectingFactoryBuilders != null) {
+        for (RedirectingFactoryBuilder redirectingFactoryBuilder
+            in redirectingFactoryBuilders) {
+          redirectingFactoryBuilder.buildOutlineExpressions(
+              classHierarchy, delayedDefaultValueCloners);
+        }
+      }
+    }
+
+    ticker.logMs("Performed redirecting factory inference");
+  }
+
+  void performTopLevelInference(List<SourceClassBuilder> sourceClasses) {
+    inferableTypes.inferTypes(typeInferenceEngine.hierarchyBuilder);
     typeInferenceEngine.isTypeInferencePrepared = true;
 
     ticker.logMs("Performed top level inference");
diff --git a/pkg/front_end/lib/src/source/source_member_builder.dart b/pkg/front_end/lib/src/source/source_member_builder.dart
index 35ce7d3..136c2fb 100644
--- a/pkg/front_end/lib/src/source/source_member_builder.dart
+++ b/pkg/front_end/lib/src/source/source_member_builder.dart
@@ -18,7 +18,6 @@
 import '../kernel/kernel_helper.dart';
 import '../type_inference/type_inference_engine.dart'
     show InferenceDataForTesting;
-import '../util/helpers.dart' show DelayedActionPerformer;
 import 'source_class_builder.dart';
 import 'source_library_builder.dart';
 
@@ -34,9 +33,7 @@
   /// Builds the core AST structures for this member as needed for the outline.
   void buildOutlineNodes(BuildNodesCallback f);
 
-  void buildOutlineExpressions(
-      ClassHierarchy classHierarchy,
-      List<DelayedActionPerformer> delayedActionPerformers,
+  void buildOutlineExpressions(ClassHierarchy classHierarchy,
       List<DelayedDefaultValueCloner> delayedDefaultValueCloners);
 
   /// Builds the AST nodes for this member as needed for the full compilation.
@@ -171,9 +168,7 @@
 
   @override
   // Coverage-ignore(suite): Not run.
-  void buildOutlineExpressions(
-      ClassHierarchy classHierarchy,
-      List<DelayedActionPerformer> delayedActionPerformers,
+  void buildOutlineExpressions(ClassHierarchy classHierarchy,
       List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {}
 
   @override
diff --git a/pkg/front_end/lib/src/source/source_type_alias_builder.dart b/pkg/front_end/lib/src/source/source_type_alias_builder.dart
index 8db6d9b..4325d2c 100644
--- a/pkg/front_end/lib/src/source/source_type_alias_builder.dart
+++ b/pkg/front_end/lib/src/source/source_type_alias_builder.dart
@@ -25,7 +25,6 @@
 import '../kernel/constructor_tearoff_lowering.dart';
 import '../kernel/expression_generator_helper.dart';
 import '../kernel/kernel_helper.dart';
-import '../util/helpers.dart';
 import 'source_library_builder.dart' show SourceLibraryBuilder;
 import 'source_loader.dart';
 
@@ -335,9 +334,7 @@
         inConstFields: inConstFields);
   }
 
-  void buildOutlineExpressions(
-      ClassHierarchy classHierarchy,
-      List<DelayedActionPerformer> delayedActionPerformers,
+  void buildOutlineExpressions(ClassHierarchy classHierarchy,
       List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
     MetadataBuilder.buildAnnotations(
         typedef,
@@ -358,7 +355,6 @@
                 inMetadata: true,
                 inConstFields: false),
             classHierarchy,
-            delayedActionPerformers,
             computeTypeParameterScope(libraryBuilder.scope));
       }
     }
diff --git a/pkg/front_end/lib/src/type_inference/inference_helper.dart b/pkg/front_end/lib/src/type_inference/inference_helper.dart
index 8899b9f..71089c2 100644
--- a/pkg/front_end/lib/src/type_inference/inference_helper.dart
+++ b/pkg/front_end/lib/src/type_inference/inference_helper.dart
@@ -5,6 +5,7 @@
 import 'package:kernel/ast.dart';
 
 import '../codes/cfe_codes.dart' show LocatedMessage, Message;
+import '../kernel/internal_ast.dart';
 
 abstract class InferenceHelper {
   Uri get uri;
@@ -28,4 +29,13 @@
   String superConstructorNameForDiagnostics(String name);
 
   String constructorNameForDiagnostics(String name, {String? className});
+
+  Expression unaliasSingleTypeAliasedConstructorInvocation(
+      TypeAliasedConstructorInvocation invocation);
+
+  Expression? resolveRedirectingFactoryTarget(
+      Procedure target, Arguments arguments, int fileOffset, bool isConst);
+
+  Expression? unaliasSingleTypeAliasedFactoryInvocation(
+      TypeAliasedFactoryInvocation invocation);
 }
diff --git a/pkg/front_end/lib/src/type_inference/inference_visitor.dart b/pkg/front_end/lib/src/type_inference/inference_visitor.dart
index 20a1c62..1dab4ce 100644
--- a/pkg/front_end/lib/src/type_inference/inference_visitor.dart
+++ b/pkg/front_end/lib/src/type_inference/inference_visitor.dart
@@ -1415,15 +1415,17 @@
         isConst: node.isConst,
         staticTarget: node.target);
     node.hasBeenInferred = true;
-    Expression resultNode = node;
     SourceLibraryBuilder library = libraryBuilder;
     if (!hadExplicitTypeArguments) {
       library.checkBoundsInFactoryInvocation(
           node, typeSchemaEnvironment, helper.uri,
           inferred: true);
     }
-    return new ExpressionInferenceResult(
-        result.inferredType, result.applyResult(resultNode));
+    Expression resolvedExpression = helper.resolveRedirectingFactoryTarget(
+        node.target, node.arguments, node.fileOffset, node.isConst)!;
+    Expression resultExpression = result.applyResult(resolvedExpression);
+
+    return new ExpressionInferenceResult(result.inferredType, resultExpression);
   }
 
   /// Returns the function type of [constructor] when called through [typedef].
@@ -1481,10 +1483,13 @@
         isConst: node.isConst,
         staticTarget: node.target);
     node.hasBeenInferred = true;
-    Expression resultNode = node;
+
+    Expression resolvedExpression =
+        helper.unaliasSingleTypeAliasedConstructorInvocation(node);
+    Expression resultingExpression = result.applyResult(resolvedExpression);
 
     return new ExpressionInferenceResult(
-        result.inferredType, result.applyResult(resultNode));
+        result.inferredType, resultingExpression);
   }
 
   /// Returns the function type of [factory] when called through [typedef].
@@ -1547,10 +1552,13 @@
         node.arguments as ArgumentsImpl,
         isConst: node.isConst,
         staticTarget: node.target);
+
+    Expression resolvedExpression =
+        helper.unaliasSingleTypeAliasedFactoryInvocation(node)!;
+    Expression resultExpression = result.applyResult(resolvedExpression);
+
     node.hasBeenInferred = true;
-    Expression resultNode = node;
-    return new ExpressionInferenceResult(
-        result.inferredType, result.applyResult(resultNode));
+    return new ExpressionInferenceResult(result.inferredType, resultExpression);
   }
 
   @override
diff --git a/pkg/front_end/lib/src/util/helpers.dart b/pkg/front_end/lib/src/util/helpers.dart
index b3eb4d5..07ce19c 100644
--- a/pkg/front_end/lib/src/util/helpers.dart
+++ b/pkg/front_end/lib/src/util/helpers.dart
@@ -7,10 +7,6 @@
 import '../api_prototype/experimental_flags.dart';
 import '../source/source_library_builder.dart';
 
-abstract class DelayedActionPerformer {
-  void performDelayedActions({required bool allowFurtherDelays});
-}
-
 /// Returns `true` if access to `Record` from `dart:core` is allowed.
 bool isRecordAccessAllowed(SourceLibraryBuilder library) {
   return library
diff --git a/pkg/front_end/test/coverage_suite_expected.dart b/pkg/front_end/test/coverage_suite_expected.dart
index f714809..9e7a7a3 100644
--- a/pkg/front_end/test/coverage_suite_expected.dart
+++ b/pkg/front_end/test/coverage_suite_expected.dart
@@ -285,7 +285,7 @@
   ),
   // 100.0%.
   "package:front_end/src/builder/formal_parameter_builder.dart": (
-    hitCount: 188,
+    hitCount: 186,
     missCount: 0,
   ),
   // 100.0%.
@@ -478,15 +478,15 @@
     hitCount: 0,
     missCount: 0,
   ),
-  // 99.34556835965287%.
+  // 99.14393499709809%.
   "package:front_end/src/kernel/body_builder.dart": (
-    hitCount: 6983,
-    missCount: 46,
+    hitCount: 6833,
+    missCount: 59,
   ),
-  // 100.0%.
+  // 98.26086956521739%.
   "package:front_end/src/kernel/body_builder_context.dart": (
-    hitCount: 345,
-    missCount: 0,
+    hitCount: 339,
+    missCount: 6,
   ),
   // 81.57894736842105%.
   "package:front_end/src/kernel/collections.dart": (
@@ -598,10 +598,10 @@
     hitCount: 1,
     missCount: 0,
   ),
-  // 100.0%.
+  // 99.12126537785588%.
   "package:front_end/src/kernel/internal_ast.dart": (
-    hitCount: 569,
-    missCount: 0,
+    hitCount: 564,
+    missCount: 5,
   ),
   // 100.0%.
   "package:front_end/src/kernel/invalid_type.dart": (
@@ -618,9 +618,9 @@
     hitCount: 285,
     missCount: 0,
   ),
-  // 99.90521327014218%.
+  // 99.90566037735849%.
   "package:front_end/src/kernel/kernel_target.dart": (
-    hitCount: 1054,
+    hitCount: 1059,
     missCount: 1,
   ),
   // 100.0%.
@@ -790,7 +790,7 @@
   ),
   // 100.0%.
   "package:front_end/src/source/source_builder_factory.dart": (
-    hitCount: 1163,
+    hitCount: 1167,
     missCount: 0,
   ),
   // 98.13664596273291%.
@@ -808,14 +808,14 @@
     hitCount: 741,
     missCount: 4,
   ),
-  // 98.31271091113611%.
+  // 98.31649831649831%.
   "package:front_end/src/source/source_constructor_builder.dart": (
-    hitCount: 874,
+    hitCount: 876,
     missCount: 15,
   ),
-  // 99.81203007518798%.
+  // 99.81024667931689%.
   "package:front_end/src/source/source_enum_builder.dart": (
-    hitCount: 531,
+    hitCount: 526,
     missCount: 1,
   ),
   // 100.0%.
@@ -831,7 +831,7 @@
   ),
   // 100.0%.
   "package:front_end/src/source/source_factory_builder.dart": (
-    hitCount: 576,
+    hitCount: 583,
     missCount: 0,
   ),
   // 100.0%.
@@ -849,9 +849,9 @@
     hitCount: 1419,
     missCount: 2,
   ),
-  // 99.89258861439313%.
+  // 99.89253089736701%.
   "package:front_end/src/source/source_loader.dart": (
-    hitCount: 1860,
+    hitCount: 1859,
     missCount: 2,
   ),
   // 100.0%.
@@ -874,9 +874,9 @@
     hitCount: 20,
     missCount: 0,
   ),
-  // 99.09909909909909%.
+  // 99.00497512437812%.
   "package:front_end/src/source/type_parameter_scope_builder.dart": (
-    hitCount: 220,
+    hitCount: 199,
     missCount: 2,
   ),
   // 100.0%.
@@ -909,9 +909,9 @@
     hitCount: 166,
     missCount: 0,
   ),
-  // 99.51504600845561%.
+  // 99.51564828614009%.
   "package:front_end/src/type_inference/inference_visitor.dart": (
-    hitCount: 8003,
+    hitCount: 8013,
     missCount: 39,
   ),
   // 99.875%.
@@ -961,7 +961,7 @@
   ),
   // 100.0%.
   "package:front_end/src/type_inference/type_inferrer.dart": (
-    hitCount: 88,
+    hitCount: 96,
     missCount: 0,
   ),
   // 100.0%.
diff --git a/pkg/front_end/testcases/extension_types/const_constructor_access.dart.strong.expect b/pkg/front_end/testcases/extension_types/const_constructor_access.dart.strong.expect
index 3d66491..f365b95 100644
--- a/pkg/front_end/testcases/extension_types/const_constructor_access.dart.strong.expect
+++ b/pkg/front_end/testcases/extension_types/const_constructor_access.dart.strong.expect
@@ -16,6 +16,11 @@
 // const newConst1 = new ExtensionType1(0); /* Error */
 //                   ^^^
 //
+// pkg/front_end/testcases/extension_types/const_constructor_access.dart:9:23: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+// Try using a constructor or factory that is 'const'.
+// const newConst1 = new ExtensionType1(0); /* Error */
+//                       ^
+//
 // pkg/front_end/testcases/extension_types/const_constructor_access.dart:13:31: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
 // Try using a constructor or factory that is 'const'.
 // const implicitConstAliased1 = Typedef1(0); /* Error */
@@ -30,6 +35,11 @@
 // const newConstAliased1 = new Typedef1(0); /* Error */
 //                          ^^^
 //
+// pkg/front_end/testcases/extension_types/const_constructor_access.dart:15:30: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+// Try using a constructor or factory that is 'const'.
+// const newConstAliased1 = new Typedef1(0); /* Error */
+//                              ^
+//
 // pkg/front_end/testcases/extension_types/const_constructor_access.dart:21:19: Error: New expression is not a constant expression.
 // const newConst2 = new ExtensionType2(0); /* Error */
 //                   ^^^
@@ -38,16 +48,6 @@
 // const newConstAliased2 = new Typedef2(0); /* Error */
 //                          ^^^
 //
-// pkg/front_end/testcases/extension_types/const_constructor_access.dart:9:23: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
-// Try using a constructor or factory that is 'const'.
-// const newConst1 = new ExtensionType1(0); /* Error */
-//                       ^
-//
-// pkg/front_end/testcases/extension_types/const_constructor_access.dart:15:30: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
-// Try using a constructor or factory that is 'const'.
-// const newConstAliased1 = new Typedef1(0); /* Error */
-//                              ^
-//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/extension_types/const_constructor_access.dart.strong.modular.expect b/pkg/front_end/testcases/extension_types/const_constructor_access.dart.strong.modular.expect
index 3d66491..f365b95 100644
--- a/pkg/front_end/testcases/extension_types/const_constructor_access.dart.strong.modular.expect
+++ b/pkg/front_end/testcases/extension_types/const_constructor_access.dart.strong.modular.expect
@@ -16,6 +16,11 @@
 // const newConst1 = new ExtensionType1(0); /* Error */
 //                   ^^^
 //
+// pkg/front_end/testcases/extension_types/const_constructor_access.dart:9:23: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+// Try using a constructor or factory that is 'const'.
+// const newConst1 = new ExtensionType1(0); /* Error */
+//                       ^
+//
 // pkg/front_end/testcases/extension_types/const_constructor_access.dart:13:31: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
 // Try using a constructor or factory that is 'const'.
 // const implicitConstAliased1 = Typedef1(0); /* Error */
@@ -30,6 +35,11 @@
 // const newConstAliased1 = new Typedef1(0); /* Error */
 //                          ^^^
 //
+// pkg/front_end/testcases/extension_types/const_constructor_access.dart:15:30: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+// Try using a constructor or factory that is 'const'.
+// const newConstAliased1 = new Typedef1(0); /* Error */
+//                              ^
+//
 // pkg/front_end/testcases/extension_types/const_constructor_access.dart:21:19: Error: New expression is not a constant expression.
 // const newConst2 = new ExtensionType2(0); /* Error */
 //                   ^^^
@@ -38,16 +48,6 @@
 // const newConstAliased2 = new Typedef2(0); /* Error */
 //                          ^^^
 //
-// pkg/front_end/testcases/extension_types/const_constructor_access.dart:9:23: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
-// Try using a constructor or factory that is 'const'.
-// const newConst1 = new ExtensionType1(0); /* Error */
-//                       ^
-//
-// pkg/front_end/testcases/extension_types/const_constructor_access.dart:15:30: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
-// Try using a constructor or factory that is 'const'.
-// const newConstAliased1 = new Typedef1(0); /* Error */
-//                              ^
-//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/extension_types/const_constructor_access.dart.strong.outline.expect b/pkg/front_end/testcases/extension_types/const_constructor_access.dart.strong.outline.expect
index a0f936d..d17b68f 100644
--- a/pkg/front_end/testcases/extension_types/const_constructor_access.dart.strong.outline.expect
+++ b/pkg/front_end/testcases/extension_types/const_constructor_access.dart.strong.outline.expect
@@ -16,6 +16,11 @@
 // const newConst1 = new ExtensionType1(0); /* Error */
 //                   ^^^
 //
+// pkg/front_end/testcases/extension_types/const_constructor_access.dart:9:23: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+// Try using a constructor or factory that is 'const'.
+// const newConst1 = new ExtensionType1(0); /* Error */
+//                       ^
+//
 // pkg/front_end/testcases/extension_types/const_constructor_access.dart:13:31: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
 // Try using a constructor or factory that is 'const'.
 // const implicitConstAliased1 = Typedef1(0); /* Error */
@@ -30,6 +35,11 @@
 // const newConstAliased1 = new Typedef1(0); /* Error */
 //                          ^^^
 //
+// pkg/front_end/testcases/extension_types/const_constructor_access.dart:15:30: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+// Try using a constructor or factory that is 'const'.
+// const newConstAliased1 = new Typedef1(0); /* Error */
+//                              ^
+//
 // pkg/front_end/testcases/extension_types/const_constructor_access.dart:21:19: Error: New expression is not a constant expression.
 // const newConst2 = new ExtensionType2(0); /* Error */
 //                   ^^^
@@ -38,16 +48,6 @@
 // const newConstAliased2 = new Typedef2(0); /* Error */
 //                          ^^^
 //
-// pkg/front_end/testcases/extension_types/const_constructor_access.dart:9:23: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
-// Try using a constructor or factory that is 'const'.
-// const newConst1 = new ExtensionType1(0); /* Error */
-//                       ^
-//
-// pkg/front_end/testcases/extension_types/const_constructor_access.dart:15:30: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
-// Try using a constructor or factory that is 'const'.
-// const newConstAliased1 = new Typedef1(0); /* Error */
-//                              ^
-//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/extension_types/const_constructor_access.dart.strong.transformed.expect b/pkg/front_end/testcases/extension_types/const_constructor_access.dart.strong.transformed.expect
index 3d66491..f365b95 100644
--- a/pkg/front_end/testcases/extension_types/const_constructor_access.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extension_types/const_constructor_access.dart.strong.transformed.expect
@@ -16,6 +16,11 @@
 // const newConst1 = new ExtensionType1(0); /* Error */
 //                   ^^^
 //
+// pkg/front_end/testcases/extension_types/const_constructor_access.dart:9:23: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+// Try using a constructor or factory that is 'const'.
+// const newConst1 = new ExtensionType1(0); /* Error */
+//                       ^
+//
 // pkg/front_end/testcases/extension_types/const_constructor_access.dart:13:31: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
 // Try using a constructor or factory that is 'const'.
 // const implicitConstAliased1 = Typedef1(0); /* Error */
@@ -30,6 +35,11 @@
 // const newConstAliased1 = new Typedef1(0); /* Error */
 //                          ^^^
 //
+// pkg/front_end/testcases/extension_types/const_constructor_access.dart:15:30: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+// Try using a constructor or factory that is 'const'.
+// const newConstAliased1 = new Typedef1(0); /* Error */
+//                              ^
+//
 // pkg/front_end/testcases/extension_types/const_constructor_access.dart:21:19: Error: New expression is not a constant expression.
 // const newConst2 = new ExtensionType2(0); /* Error */
 //                   ^^^
@@ -38,16 +48,6 @@
 // const newConstAliased2 = new Typedef2(0); /* Error */
 //                          ^^^
 //
-// pkg/front_end/testcases/extension_types/const_constructor_access.dart:9:23: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
-// Try using a constructor or factory that is 'const'.
-// const newConst1 = new ExtensionType1(0); /* Error */
-//                       ^
-//
-// pkg/front_end/testcases/extension_types/const_constructor_access.dart:15:30: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
-// Try using a constructor or factory that is 'const'.
-// const newConstAliased1 = new Typedef1(0); /* Error */
-//                              ^
-//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/general/bounds_instances.dart.strong.expect b/pkg/front_end/testcases/general/bounds_instances.dart.strong.expect
index 10849bb..0e07d33a 100644
--- a/pkg/front_end/testcases/general/bounds_instances.dart.strong.expect
+++ b/pkg/front_end/testcases/general/bounds_instances.dart.strong.expect
@@ -94,6 +94,16 @@
 // class G<X extends Class<X>> {}
 //         ^
 //
+// pkg/front_end/testcases/general/bounds_instances.dart:16:7: Error: Inferred type argument 'Class<Object?>' doesn't conform to the bound 'Class<X>' of the type variable 'X' on 'F'.
+//  - 'Class' is from 'pkg/front_end/testcases/general/bounds_instances.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   new F(); // Error
+//       ^
+// pkg/front_end/testcases/general/bounds_instances.dart:9:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef F<X extends Class<X>> = Class1;
+//           ^
+//
 // pkg/front_end/testcases/general/bounds_instances.dart:24:7: Error: Inferred type argument 'Class<Object?>' doesn't conform to the bound 'Class<X>' of the type variable 'X' on 'G'.
 //  - 'Class' is from 'pkg/front_end/testcases/general/bounds_instances.dart'.
 //  - 'Object' is from 'dart:core'.
@@ -140,16 +150,6 @@
 //   G<int>.new; // Error
 //   ^
 //
-// pkg/front_end/testcases/general/bounds_instances.dart:16:7: Error: Inferred type argument 'Class<Object?>' doesn't conform to the bound 'Class<X>' of the type variable 'X' on 'F'.
-//  - 'Class' is from 'pkg/front_end/testcases/general/bounds_instances.dart'.
-//  - 'Object' is from 'dart:core'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//   new F(); // Error
-//       ^
-// pkg/front_end/testcases/general/bounds_instances.dart:9:11: Context: This is the type variable whose bound isn't conformed to.
-// typedef F<X extends Class<X>> = Class1;
-//           ^
-//
 // pkg/front_end/testcases/general/bounds_instances.dart:39:3: Error: Type argument 'Object' doesn't conform to the bound 'Class<X>' of the type variable 'X' on 'F'.
 //  - 'Object' is from 'dart:core'.
 //  - 'Class' is from 'pkg/front_end/testcases/general/bounds_instances.dart'.
diff --git a/pkg/front_end/testcases/general/bounds_instances.dart.strong.modular.expect b/pkg/front_end/testcases/general/bounds_instances.dart.strong.modular.expect
index 10849bb..0e07d33a 100644
--- a/pkg/front_end/testcases/general/bounds_instances.dart.strong.modular.expect
+++ b/pkg/front_end/testcases/general/bounds_instances.dart.strong.modular.expect
@@ -94,6 +94,16 @@
 // class G<X extends Class<X>> {}
 //         ^
 //
+// pkg/front_end/testcases/general/bounds_instances.dart:16:7: Error: Inferred type argument 'Class<Object?>' doesn't conform to the bound 'Class<X>' of the type variable 'X' on 'F'.
+//  - 'Class' is from 'pkg/front_end/testcases/general/bounds_instances.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   new F(); // Error
+//       ^
+// pkg/front_end/testcases/general/bounds_instances.dart:9:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef F<X extends Class<X>> = Class1;
+//           ^
+//
 // pkg/front_end/testcases/general/bounds_instances.dart:24:7: Error: Inferred type argument 'Class<Object?>' doesn't conform to the bound 'Class<X>' of the type variable 'X' on 'G'.
 //  - 'Class' is from 'pkg/front_end/testcases/general/bounds_instances.dart'.
 //  - 'Object' is from 'dart:core'.
@@ -140,16 +150,6 @@
 //   G<int>.new; // Error
 //   ^
 //
-// pkg/front_end/testcases/general/bounds_instances.dart:16:7: Error: Inferred type argument 'Class<Object?>' doesn't conform to the bound 'Class<X>' of the type variable 'X' on 'F'.
-//  - 'Class' is from 'pkg/front_end/testcases/general/bounds_instances.dart'.
-//  - 'Object' is from 'dart:core'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//   new F(); // Error
-//       ^
-// pkg/front_end/testcases/general/bounds_instances.dart:9:11: Context: This is the type variable whose bound isn't conformed to.
-// typedef F<X extends Class<X>> = Class1;
-//           ^
-//
 // pkg/front_end/testcases/general/bounds_instances.dart:39:3: Error: Type argument 'Object' doesn't conform to the bound 'Class<X>' of the type variable 'X' on 'F'.
 //  - 'Object' is from 'dart:core'.
 //  - 'Class' is from 'pkg/front_end/testcases/general/bounds_instances.dart'.
diff --git a/pkg/front_end/testcases/general/bounds_instances.dart.strong.transformed.expect b/pkg/front_end/testcases/general/bounds_instances.dart.strong.transformed.expect
index 10849bb..0e07d33a 100644
--- a/pkg/front_end/testcases/general/bounds_instances.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/bounds_instances.dart.strong.transformed.expect
@@ -94,6 +94,16 @@
 // class G<X extends Class<X>> {}
 //         ^
 //
+// pkg/front_end/testcases/general/bounds_instances.dart:16:7: Error: Inferred type argument 'Class<Object?>' doesn't conform to the bound 'Class<X>' of the type variable 'X' on 'F'.
+//  - 'Class' is from 'pkg/front_end/testcases/general/bounds_instances.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   new F(); // Error
+//       ^
+// pkg/front_end/testcases/general/bounds_instances.dart:9:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef F<X extends Class<X>> = Class1;
+//           ^
+//
 // pkg/front_end/testcases/general/bounds_instances.dart:24:7: Error: Inferred type argument 'Class<Object?>' doesn't conform to the bound 'Class<X>' of the type variable 'X' on 'G'.
 //  - 'Class' is from 'pkg/front_end/testcases/general/bounds_instances.dart'.
 //  - 'Object' is from 'dart:core'.
@@ -140,16 +150,6 @@
 //   G<int>.new; // Error
 //   ^
 //
-// pkg/front_end/testcases/general/bounds_instances.dart:16:7: Error: Inferred type argument 'Class<Object?>' doesn't conform to the bound 'Class<X>' of the type variable 'X' on 'F'.
-//  - 'Class' is from 'pkg/front_end/testcases/general/bounds_instances.dart'.
-//  - 'Object' is from 'dart:core'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//   new F(); // Error
-//       ^
-// pkg/front_end/testcases/general/bounds_instances.dart:9:11: Context: This is the type variable whose bound isn't conformed to.
-// typedef F<X extends Class<X>> = Class1;
-//           ^
-//
 // pkg/front_end/testcases/general/bounds_instances.dart:39:3: Error: Type argument 'Object' doesn't conform to the bound 'Class<X>' of the type variable 'X' on 'F'.
 //  - 'Object' is from 'dart:core'.
 //  - 'Class' is from 'pkg/front_end/testcases/general/bounds_instances.dart'.
diff --git a/pkg/front_end/testcases/general/constructor_inference_interdependence.dart b/pkg/front_end/testcases/general/constructor_inference_interdependence.dart
new file mode 100644
index 0000000..cd9eabd
--- /dev/null
+++ b/pkg/front_end/testcases/general/constructor_inference_interdependence.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2024, 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 C {}
+
+sealed class B<X> {
+  final C? Function()? foo;
+  const B({required this.foo});
+
+  const factory B.redir({C? Function()? foo}) = A;
+}
+
+mixin M {}
+
+final class A<X> extends B<X> with M {
+  const A({super.foo = null}) : super();
+}
+
+main() {
+  print(new A());
+}
diff --git a/pkg/front_end/testcases/general/constructor_inference_interdependence.dart.strong.expect b/pkg/front_end/testcases/general/constructor_inference_interdependence.dart.strong.expect
new file mode 100644
index 0000000..0db728b
--- /dev/null
+++ b/pkg/front_end/testcases/general/constructor_inference_interdependence.dart.strong.expect
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+}
+abstract sealed class B<X extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field () →? self::C? foo;
+  const constructor •({required () →? self::C? foo}) → self::B<self::B::X%>
+    : self::B::foo = foo, super core::Object::•()
+    ;
+  static factory redir<X extends core::Object? = dynamic>({() →? self::C? foo = #C1}) → self::B<self::B::redir::X%> /* redirection-target: self::A::•<self::B::redir::X%>*/
+    return new self::A::•<self::B::redir::X%>(foo: foo);
+}
+abstract class M extends core::Object /*isMixinDeclaration*/  {
+}
+abstract sealed class _A&B&M<X extends core::Object? = dynamic> = self::B<self::_A&B&M::X%> with self::M /*isAnonymousMixin,hasConstConstructor*/  {
+  const synthetic constructor •({required () →? self::C? foo}) → self::_A&B&M<self::_A&B&M::X%>
+    : super self::B::•(foo: foo)
+    ;
+}
+final class A<X extends core::Object? = dynamic> extends self::_A&B&M<self::A::X%> /*hasConstConstructor*/  {
+  const constructor •({has-declared-initializer () →? self::C? foo = #C1}) → self::A<self::A::X%>
+    : super self::_A&B&M::•(foo: foo)
+    ;
+}
+static method main() → dynamic {
+  core::print(new self::A::•<dynamic>());
+}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/general/constructor_inference_interdependence.dart.strong.modular.expect b/pkg/front_end/testcases/general/constructor_inference_interdependence.dart.strong.modular.expect
new file mode 100644
index 0000000..0db728b
--- /dev/null
+++ b/pkg/front_end/testcases/general/constructor_inference_interdependence.dart.strong.modular.expect
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+}
+abstract sealed class B<X extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field () →? self::C? foo;
+  const constructor •({required () →? self::C? foo}) → self::B<self::B::X%>
+    : self::B::foo = foo, super core::Object::•()
+    ;
+  static factory redir<X extends core::Object? = dynamic>({() →? self::C? foo = #C1}) → self::B<self::B::redir::X%> /* redirection-target: self::A::•<self::B::redir::X%>*/
+    return new self::A::•<self::B::redir::X%>(foo: foo);
+}
+abstract class M extends core::Object /*isMixinDeclaration*/  {
+}
+abstract sealed class _A&B&M<X extends core::Object? = dynamic> = self::B<self::_A&B&M::X%> with self::M /*isAnonymousMixin,hasConstConstructor*/  {
+  const synthetic constructor •({required () →? self::C? foo}) → self::_A&B&M<self::_A&B&M::X%>
+    : super self::B::•(foo: foo)
+    ;
+}
+final class A<X extends core::Object? = dynamic> extends self::_A&B&M<self::A::X%> /*hasConstConstructor*/  {
+  const constructor •({has-declared-initializer () →? self::C? foo = #C1}) → self::A<self::A::X%>
+    : super self::_A&B&M::•(foo: foo)
+    ;
+}
+static method main() → dynamic {
+  core::print(new self::A::•<dynamic>());
+}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/general/constructor_inference_interdependence.dart.strong.outline.expect b/pkg/front_end/testcases/general/constructor_inference_interdependence.dart.strong.outline.expect
new file mode 100644
index 0000000..af6da57
--- /dev/null
+++ b/pkg/front_end/testcases/general/constructor_inference_interdependence.dart.strong.outline.expect
@@ -0,0 +1,30 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    ;
+}
+abstract sealed class B<X extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field () →? self::C? foo;
+  const constructor •({required () →? self::C? foo}) → self::B<self::B::X%>
+    : self::B::foo = foo, super core::Object::•()
+    ;
+  static factory redir<X extends core::Object? = dynamic>({() →? self::C? foo = null}) → self::B<self::B::redir::X%> /* redirection-target: self::A::•<self::B::redir::X%>*/
+    return new self::A::•<self::B::redir::X%>(foo: foo);
+}
+abstract class M extends core::Object /*isMixinDeclaration*/  {
+}
+abstract sealed class _A&B&M<X extends core::Object? = dynamic> = self::B<self::_A&B&M::X%> with self::M /*isAnonymousMixin,hasConstConstructor*/  {
+  const synthetic constructor •({required () →? self::C? foo}) → self::_A&B&M<self::_A&B&M::X%>
+    : super self::B::•(foo: foo)
+    ;
+}
+final class A<X extends core::Object? = dynamic> extends self::_A&B&M<self::A::X%> /*hasConstConstructor*/  {
+  const constructor •({has-declared-initializer () →? self::C? foo = null}) → self::A<self::A::X%>
+    : super self::_A&B&M::•(foo: foo)
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/constructor_inference_interdependence.dart.strong.transformed.expect b/pkg/front_end/testcases/general/constructor_inference_interdependence.dart.strong.transformed.expect
new file mode 100644
index 0000000..b0993ad
--- /dev/null
+++ b/pkg/front_end/testcases/general/constructor_inference_interdependence.dart.strong.transformed.expect
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+}
+abstract sealed class B<X extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field () →? self::C? foo;
+  const constructor •({required () →? self::C? foo}) → self::B<self::B::X%>
+    : self::B::foo = foo, super core::Object::•()
+    ;
+  static factory redir<X extends core::Object? = dynamic>({() →? self::C? foo = #C1}) → self::B<self::B::redir::X%> /* redirection-target: self::A::•<self::B::redir::X%>*/
+    return new self::A::•<self::B::redir::X%>(foo: foo);
+}
+abstract class M extends core::Object /*isMixinDeclaration*/  {
+}
+abstract sealed class _A&B&M<X extends core::Object? = dynamic> extends self::B<self::_A&B&M::X%> implements self::M /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/  {
+  const synthetic constructor •({required () →? self::C? foo}) → self::_A&B&M<self::_A&B&M::X%>
+    : super self::B::•(foo: foo)
+    ;
+}
+final class A<X extends core::Object? = dynamic> extends self::_A&B&M<self::A::X%> /*hasConstConstructor*/  {
+  const constructor •({has-declared-initializer () →? self::C? foo = #C1}) → self::A<self::A::X%>
+    : super self::_A&B&M::•(foo: foo)
+    ;
+}
+static method main() → dynamic {
+  core::print(new self::A::•<dynamic>());
+}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/general/constructor_inference_interdependence.dart.textual_outline.expect b/pkg/front_end/testcases/general/constructor_inference_interdependence.dart.textual_outline.expect
new file mode 100644
index 0000000..dc73668
--- /dev/null
+++ b/pkg/front_end/testcases/general/constructor_inference_interdependence.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+class C {}
+
+sealed class B<X> {
+  final C? Function()? foo;
+  const B({required this.foo});
+  const factory B.redir({C? Function()? foo}) = A;
+}
+
+mixin M {}
+
+final class A<X> extends B<X> with M {
+  const A({super.foo = null}) : super();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/constructor_inference_interdependence.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/constructor_inference_interdependence.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8c1259b
--- /dev/null
+++ b/pkg/front_end/testcases/general/constructor_inference_interdependence.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+class C {}
+
+final class A<X> extends B<X> with M {
+  const A({super.foo = null}) : super();
+}
+
+main() {}
+
+mixin M {}
+
+sealed class B<X> {
+  const B({required this.foo});
+  const factory B.redir({C? Function()? foo}) = A;
+  final C? Function()? foo;
+}
diff --git a/pkg/front_end/testcases/general/redirecting_constructors_declaration_order.dart b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order.dart
new file mode 100644
index 0000000..cad4e75
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2024, 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 C {
+  List<A> field;
+  C({this.field = const [A.redir()]});
+}
+
+abstract class A {
+  const factory A.redir() = B;
+}
+
+class B<X> implements A {
+  const B();
+}
diff --git a/pkg/front_end/testcases/general/redirecting_constructors_declaration_order.dart.strong.expect b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order.dart.strong.expect
new file mode 100644
index 0000000..2d6194a
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order.dart.strong.expect
@@ -0,0 +1,30 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::List<self::A> field;
+  constructor •({core::List<self::A> field = #C2}) → self::C
+    : self::C::field = field, super core::Object::•()
+    ;
+}
+abstract class A extends core::Object {
+  static factory redir() → self::A /* redirection-target: self::B::•<dynamic>*/
+    return new self::B::•<dynamic>();
+}
+class B<X extends core::Object? = dynamic> extends core::Object implements self::A /*hasConstConstructor*/  {
+  const constructor •() → self::B<self::B::X%>
+    : super core::Object::•()
+    ;
+}
+
+constants  {
+  #C1 = self::B<dynamic> {}
+  #C2 = <self::A>[#C1]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///redirecting_constructors_declaration_order.dart:
+- B. (from org-dartlang-testcase:///redirecting_constructors_declaration_order.dart:15:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
diff --git a/pkg/front_end/testcases/general/redirecting_constructors_declaration_order.dart.strong.modular.expect b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order.dart.strong.modular.expect
new file mode 100644
index 0000000..2d6194a
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order.dart.strong.modular.expect
@@ -0,0 +1,30 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::List<self::A> field;
+  constructor •({core::List<self::A> field = #C2}) → self::C
+    : self::C::field = field, super core::Object::•()
+    ;
+}
+abstract class A extends core::Object {
+  static factory redir() → self::A /* redirection-target: self::B::•<dynamic>*/
+    return new self::B::•<dynamic>();
+}
+class B<X extends core::Object? = dynamic> extends core::Object implements self::A /*hasConstConstructor*/  {
+  const constructor •() → self::B<self::B::X%>
+    : super core::Object::•()
+    ;
+}
+
+constants  {
+  #C1 = self::B<dynamic> {}
+  #C2 = <self::A>[#C1]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///redirecting_constructors_declaration_order.dart:
+- B. (from org-dartlang-testcase:///redirecting_constructors_declaration_order.dart:15:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
diff --git a/pkg/front_end/testcases/general/redirecting_constructors_declaration_order.dart.strong.outline.expect b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order.dart.strong.outline.expect
new file mode 100644
index 0000000..b288ecc
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order.dart.strong.outline.expect
@@ -0,0 +1,23 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::List<self::A> field;
+  constructor •({core::List<self::A> field = const <self::A>[const self::B::•<dynamic>()]}) → self::C
+    ;
+}
+abstract class A extends core::Object {
+  static factory redir() → self::A /* redirection-target: self::B::•<dynamic>*/
+    return new self::B::•<dynamic>();
+}
+class B<X extends core::Object? = dynamic> extends core::Object implements self::A /*hasConstConstructor*/  {
+  const constructor •() → self::B<self::B::X%>
+    : super core::Object::•()
+    ;
+}
+
+
+Extra constant evaluation status:
+Evaluated: ListLiteral @ org-dartlang-testcase:///redirecting_constructors_declaration_order.dart:7:19 -> ListConstant(const <A>[const B<dynamic>{}])
+Extra constant evaluation: evaluated: 2, effectively constant: 1
diff --git a/pkg/front_end/testcases/general/redirecting_constructors_declaration_order.dart.strong.transformed.expect b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order.dart.strong.transformed.expect
new file mode 100644
index 0000000..2d6194a
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order.dart.strong.transformed.expect
@@ -0,0 +1,30 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::List<self::A> field;
+  constructor •({core::List<self::A> field = #C2}) → self::C
+    : self::C::field = field, super core::Object::•()
+    ;
+}
+abstract class A extends core::Object {
+  static factory redir() → self::A /* redirection-target: self::B::•<dynamic>*/
+    return new self::B::•<dynamic>();
+}
+class B<X extends core::Object? = dynamic> extends core::Object implements self::A /*hasConstConstructor*/  {
+  const constructor •() → self::B<self::B::X%>
+    : super core::Object::•()
+    ;
+}
+
+constants  {
+  #C1 = self::B<dynamic> {}
+  #C2 = <self::A>[#C1]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///redirecting_constructors_declaration_order.dart:
+- B. (from org-dartlang-testcase:///redirecting_constructors_declaration_order.dart:15:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
diff --git a/pkg/front_end/testcases/general/redirecting_constructors_declaration_order.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order.dart.textual_outline.expect
new file mode 100644
index 0000000..3ce5bdc
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+class C {
+  List<A> field;
+  C({this.field = const [A.redir()]});
+}
+
+abstract class A {
+  const factory A.redir() = B;
+}
+
+class B<X> implements A {
+  const B();
+}
diff --git a/pkg/front_end/testcases/general/redirecting_constructors_declaration_order.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0d599f9
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+abstract class A {
+  const factory A.redir() = B;
+}
+
+class B<X> implements A {
+  const B();
+}
+
+class C {
+  C({this.field = const [A.redir()]});
+  List<A> field;
+}
diff --git a/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_2.dart b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_2.dart
new file mode 100644
index 0000000..4d57560
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_2.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2024, 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 C {
+  List<A> field;
+  C.named1({this.field = const [A.redir1(0, s: "")]});
+  C.named2({this.field = const [A.redir1(s: "", 0)]});
+}
+
+abstract class A {
+  const factory A.redir1(int x, {required String s}) = B;
+  const factory A.redir2(int x, {required String s}) = B;
+}
+
+class B<X> implements A {
+  const B(int x, {required String s});
+}
+
+test() {
+  new A.redir2(0, s: "");
+  new A.redir2(s: "", 0);
+}
diff --git a/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_2.dart.strong.expect b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_2.dart.strong.expect
new file mode 100644
index 0000000..8db2dcf
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_2.dart.strong.expect
@@ -0,0 +1,39 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::List<self::A> field;
+  constructor named1({core::List<self::A> field = #C2}) → self::C
+    : self::C::field = field, super core::Object::•()
+    ;
+  constructor named2({core::List<self::A> field = #C2}) → self::C
+    : self::C::field = field, super core::Object::•()
+    ;
+}
+abstract class A extends core::Object {
+  static factory redir1(core::int x, {required core::String s}) → self::A /* redirection-target: self::B::•<dynamic>*/
+    return new self::B::•<dynamic>(x, s: s);
+  static factory redir2(core::int x, {required core::String s}) → self::A /* redirection-target: self::B::•<dynamic>*/
+    return new self::B::•<dynamic>(x, s: s);
+}
+class B<X extends core::Object? = dynamic> extends core::Object implements self::A /*hasConstConstructor*/  {
+  const constructor •(core::int x, {required core::String s}) → self::B<self::B::X%>
+    : super core::Object::•()
+    ;
+}
+static method test() → dynamic {
+  new self::B::•<dynamic>(0, s: "");
+  let final core::String #t1 = "" in new self::B::•<dynamic>(0, s: #t1);
+}
+
+constants  {
+  #C1 = self::B<dynamic> {}
+  #C2 = <self::A>[#C1]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///redirecting_constructors_declaration_order_2.dart:
+- B. (from org-dartlang-testcase:///redirecting_constructors_declaration_order_2.dart:17:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
diff --git a/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_2.dart.strong.modular.expect b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_2.dart.strong.modular.expect
new file mode 100644
index 0000000..8db2dcf
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_2.dart.strong.modular.expect
@@ -0,0 +1,39 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::List<self::A> field;
+  constructor named1({core::List<self::A> field = #C2}) → self::C
+    : self::C::field = field, super core::Object::•()
+    ;
+  constructor named2({core::List<self::A> field = #C2}) → self::C
+    : self::C::field = field, super core::Object::•()
+    ;
+}
+abstract class A extends core::Object {
+  static factory redir1(core::int x, {required core::String s}) → self::A /* redirection-target: self::B::•<dynamic>*/
+    return new self::B::•<dynamic>(x, s: s);
+  static factory redir2(core::int x, {required core::String s}) → self::A /* redirection-target: self::B::•<dynamic>*/
+    return new self::B::•<dynamic>(x, s: s);
+}
+class B<X extends core::Object? = dynamic> extends core::Object implements self::A /*hasConstConstructor*/  {
+  const constructor •(core::int x, {required core::String s}) → self::B<self::B::X%>
+    : super core::Object::•()
+    ;
+}
+static method test() → dynamic {
+  new self::B::•<dynamic>(0, s: "");
+  let final core::String #t1 = "" in new self::B::•<dynamic>(0, s: #t1);
+}
+
+constants  {
+  #C1 = self::B<dynamic> {}
+  #C2 = <self::A>[#C1]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///redirecting_constructors_declaration_order_2.dart:
+- B. (from org-dartlang-testcase:///redirecting_constructors_declaration_order_2.dart:17:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
diff --git a/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_2.dart.strong.outline.expect b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_2.dart.strong.outline.expect
new file mode 100644
index 0000000..f58b613
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_2.dart.strong.outline.expect
@@ -0,0 +1,30 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::List<self::A> field;
+  constructor named1({core::List<self::A> field = const <self::A>[const self::B::•<dynamic>(0, s: "")]}) → self::C
+    ;
+  constructor named2({core::List<self::A> field = const <self::A>[const self::B::•<dynamic>(0, s: "")]}) → self::C
+    ;
+}
+abstract class A extends core::Object {
+  static factory redir1(core::int x, {required core::String s}) → self::A /* redirection-target: self::B::•<dynamic>*/
+    return new self::B::•<dynamic>(x, s: s);
+  static factory redir2(core::int x, {required core::String s}) → self::A /* redirection-target: self::B::•<dynamic>*/
+    return new self::B::•<dynamic>(x, s: s);
+}
+class B<X extends core::Object? = dynamic> extends core::Object implements self::A /*hasConstConstructor*/  {
+  const constructor •(core::int x, {required core::String s}) → self::B<self::B::X%>
+    : super core::Object::•()
+    ;
+}
+static method test() → dynamic
+  ;
+
+
+Extra constant evaluation status:
+Evaluated: ListLiteral @ org-dartlang-testcase:///redirecting_constructors_declaration_order_2.dart:7:26 -> ListConstant(const <A>[const B<dynamic>{}])
+Evaluated: ListLiteral @ org-dartlang-testcase:///redirecting_constructors_declaration_order_2.dart:8:26 -> ListConstant(const <A>[const B<dynamic>{}])
+Extra constant evaluation: evaluated: 8, effectively constant: 2
diff --git a/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_2.dart.strong.transformed.expect b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_2.dart.strong.transformed.expect
new file mode 100644
index 0000000..105c064
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_2.dart.strong.transformed.expect
@@ -0,0 +1,43 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::List<self::A> field;
+  constructor named1({core::List<self::A> field = #C2}) → self::C
+    : self::C::field = field, super core::Object::•()
+    ;
+  constructor named2({core::List<self::A> field = #C2}) → self::C
+    : self::C::field = field, super core::Object::•()
+    ;
+}
+abstract class A extends core::Object {
+  static factory redir1(core::int x, {required core::String s}) → self::A /* redirection-target: self::B::•<dynamic>*/
+    return new self::B::•<dynamic>(x, s: s);
+  static factory redir2(core::int x, {required core::String s}) → self::A /* redirection-target: self::B::•<dynamic>*/
+    return new self::B::•<dynamic>(x, s: s);
+}
+class B<X extends core::Object? = dynamic> extends core::Object implements self::A /*hasConstConstructor*/  {
+  const constructor •(core::int x, {required core::String s}) → self::B<self::B::X%>
+    : super core::Object::•()
+    ;
+}
+static method test() → dynamic {
+  new self::B::•<dynamic>(0, s: "");
+  let final core::String #t1 = "" in new self::B::•<dynamic>(0, s: #t1);
+}
+
+constants  {
+  #C1 = self::B<dynamic> {}
+  #C2 = <self::A>[#C1]
+}
+
+Extra constant evaluation status:
+Evaluated: VariableGet @ org-dartlang-testcase:///redirecting_constructors_declaration_order_2.dart:22:19 -> StringConstant("")
+Extra constant evaluation: evaluated: 12, effectively constant: 1
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///redirecting_constructors_declaration_order_2.dart:
+- B. (from org-dartlang-testcase:///redirecting_constructors_declaration_order_2.dart:17:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
diff --git a/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_2.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_2.dart.textual_outline.expect
new file mode 100644
index 0000000..c262d64
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_2.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+class C {
+  List<A> field;
+  C.named1({this.field = const [A.redir1(0, s: "")]});
+  C.named2({this.field = const [A.redir1(s: "", 0)]});
+}
+
+abstract class A {
+  const factory A.redir1(int x, {required String s}) = B;
+  const factory A.redir2(int x, {required String s}) = B;
+}
+
+class B<X> implements A {
+  const B(int x, {required String s});
+}
+
+test() {}
diff --git a/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..606c5ac
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+abstract class A {
+  const factory A.redir1(int x, {required String s}) = B;
+  const factory A.redir2(int x, {required String s}) = B;
+}
+
+class B<X> implements A {
+  const B(int x, {required String s});
+}
+
+class C {
+  C.named1({this.field = const [A.redir1(0, s: "")]});
+  C.named2({this.field = const [A.redir1(s: "", 0)]});
+  List<A> field;
+}
+
+test() {}
diff --git a/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_3.dart b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_3.dart
new file mode 100644
index 0000000..757e8d6
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_3.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2024, 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 C {
+  List<A<bool>> field;
+  C.named1({this.field = const [A.redir1(0, s: "")]});
+  C.named2({this.field = const [A.redir1(s: "", 0)]});
+}
+
+abstract class A<X> {
+  const factory A.redir1(int x, {required String s}) = B;
+  const factory A.redir2(int x, {required String s}) = B;
+}
+
+class B<Y> implements A<Y> {
+  const B(int x, {required String s});
+}
+
+test() {
+  A<String> foo1 = new A.redir2(0, s: "");
+  A<num> foo2 = new A.redir2(s: "", 0);
+}
diff --git a/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_3.dart.strong.expect b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_3.dart.strong.expect
new file mode 100644
index 0000000..61b3f85
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_3.dart.strong.expect
@@ -0,0 +1,39 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::List<self::A<core::bool>> field;
+  constructor named1({core::List<self::A<core::bool>> field = #C2}) → self::C
+    : self::C::field = field, super core::Object::•()
+    ;
+  constructor named2({core::List<self::A<core::bool>> field = #C2}) → self::C
+    : self::C::field = field, super core::Object::•()
+    ;
+}
+abstract class A<X extends core::Object? = dynamic> extends core::Object {
+  static factory redir1<X extends core::Object? = dynamic>(core::int x, {required core::String s}) → self::A<self::A::redir1::X%> /* redirection-target: self::B::•<self::A::redir1::X%>*/
+    return new self::B::•<self::A::redir1::X%>(x, s: s);
+  static factory redir2<X extends core::Object? = dynamic>(core::int x, {required core::String s}) → self::A<self::A::redir2::X%> /* redirection-target: self::B::•<self::A::redir2::X%>*/
+    return new self::B::•<self::A::redir2::X%>(x, s: s);
+}
+class B<Y extends core::Object? = dynamic> extends core::Object implements self::A<self::B::Y%> /*hasConstConstructor*/  {
+  const constructor •(core::int x, {required core::String s}) → self::B<self::B::Y%>
+    : super core::Object::•()
+    ;
+}
+static method test() → dynamic {
+  self::A<core::String> foo1 = new self::B::•<core::String>(0, s: "");
+  self::A<core::num> foo2 = let final core::String #t1 = "" in new self::B::•<core::num>(0, s: #t1);
+}
+
+constants  {
+  #C1 = self::B<core::bool> {}
+  #C2 = <self::A<core::bool>>[#C1]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///redirecting_constructors_declaration_order_3.dart:
+- B. (from org-dartlang-testcase:///redirecting_constructors_declaration_order_3.dart:17:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
diff --git a/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_3.dart.strong.modular.expect b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_3.dart.strong.modular.expect
new file mode 100644
index 0000000..61b3f85
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_3.dart.strong.modular.expect
@@ -0,0 +1,39 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::List<self::A<core::bool>> field;
+  constructor named1({core::List<self::A<core::bool>> field = #C2}) → self::C
+    : self::C::field = field, super core::Object::•()
+    ;
+  constructor named2({core::List<self::A<core::bool>> field = #C2}) → self::C
+    : self::C::field = field, super core::Object::•()
+    ;
+}
+abstract class A<X extends core::Object? = dynamic> extends core::Object {
+  static factory redir1<X extends core::Object? = dynamic>(core::int x, {required core::String s}) → self::A<self::A::redir1::X%> /* redirection-target: self::B::•<self::A::redir1::X%>*/
+    return new self::B::•<self::A::redir1::X%>(x, s: s);
+  static factory redir2<X extends core::Object? = dynamic>(core::int x, {required core::String s}) → self::A<self::A::redir2::X%> /* redirection-target: self::B::•<self::A::redir2::X%>*/
+    return new self::B::•<self::A::redir2::X%>(x, s: s);
+}
+class B<Y extends core::Object? = dynamic> extends core::Object implements self::A<self::B::Y%> /*hasConstConstructor*/  {
+  const constructor •(core::int x, {required core::String s}) → self::B<self::B::Y%>
+    : super core::Object::•()
+    ;
+}
+static method test() → dynamic {
+  self::A<core::String> foo1 = new self::B::•<core::String>(0, s: "");
+  self::A<core::num> foo2 = let final core::String #t1 = "" in new self::B::•<core::num>(0, s: #t1);
+}
+
+constants  {
+  #C1 = self::B<core::bool> {}
+  #C2 = <self::A<core::bool>>[#C1]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///redirecting_constructors_declaration_order_3.dart:
+- B. (from org-dartlang-testcase:///redirecting_constructors_declaration_order_3.dart:17:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
diff --git a/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_3.dart.strong.outline.expect b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_3.dart.strong.outline.expect
new file mode 100644
index 0000000..51200e0
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_3.dart.strong.outline.expect
@@ -0,0 +1,30 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::List<self::A<core::bool>> field;
+  constructor named1({core::List<self::A<core::bool>> field = const <self::A<core::bool>>[const self::B::•<core::bool>(0, s: "")]}) → self::C
+    ;
+  constructor named2({core::List<self::A<core::bool>> field = const <self::A<core::bool>>[const self::B::•<core::bool>(0, s: "")]}) → self::C
+    ;
+}
+abstract class A<X extends core::Object? = dynamic> extends core::Object {
+  static factory redir1<X extends core::Object? = dynamic>(core::int x, {required core::String s}) → self::A<self::A::redir1::X%> /* redirection-target: self::B::•<self::A::redir1::X%>*/
+    return new self::B::•<self::A::redir1::X%>(x, s: s);
+  static factory redir2<X extends core::Object? = dynamic>(core::int x, {required core::String s}) → self::A<self::A::redir2::X%> /* redirection-target: self::B::•<self::A::redir2::X%>*/
+    return new self::B::•<self::A::redir2::X%>(x, s: s);
+}
+class B<Y extends core::Object? = dynamic> extends core::Object implements self::A<self::B::Y%> /*hasConstConstructor*/  {
+  const constructor •(core::int x, {required core::String s}) → self::B<self::B::Y%>
+    : super core::Object::•()
+    ;
+}
+static method test() → dynamic
+  ;
+
+
+Extra constant evaluation status:
+Evaluated: ListLiteral @ org-dartlang-testcase:///redirecting_constructors_declaration_order_3.dart:7:26 -> ListConstant(const <A<bool>>[const B<bool>{}])
+Evaluated: ListLiteral @ org-dartlang-testcase:///redirecting_constructors_declaration_order_3.dart:8:26 -> ListConstant(const <A<bool>>[const B<bool>{}])
+Extra constant evaluation: evaluated: 8, effectively constant: 2
diff --git a/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_3.dart.strong.transformed.expect b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_3.dart.strong.transformed.expect
new file mode 100644
index 0000000..c1da56f
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_3.dart.strong.transformed.expect
@@ -0,0 +1,43 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::List<self::A<core::bool>> field;
+  constructor named1({core::List<self::A<core::bool>> field = #C2}) → self::C
+    : self::C::field = field, super core::Object::•()
+    ;
+  constructor named2({core::List<self::A<core::bool>> field = #C2}) → self::C
+    : self::C::field = field, super core::Object::•()
+    ;
+}
+abstract class A<X extends core::Object? = dynamic> extends core::Object {
+  static factory redir1<X extends core::Object? = dynamic>(core::int x, {required core::String s}) → self::A<self::A::redir1::X%> /* redirection-target: self::B::•<self::A::redir1::X%>*/
+    return new self::B::•<self::A::redir1::X%>(x, s: s);
+  static factory redir2<X extends core::Object? = dynamic>(core::int x, {required core::String s}) → self::A<self::A::redir2::X%> /* redirection-target: self::B::•<self::A::redir2::X%>*/
+    return new self::B::•<self::A::redir2::X%>(x, s: s);
+}
+class B<Y extends core::Object? = dynamic> extends core::Object implements self::A<self::B::Y%> /*hasConstConstructor*/  {
+  const constructor •(core::int x, {required core::String s}) → self::B<self::B::Y%>
+    : super core::Object::•()
+    ;
+}
+static method test() → dynamic {
+  self::A<core::String> foo1 = new self::B::•<core::String>(0, s: "");
+  self::A<core::num> foo2 = let final core::String #t1 = "" in new self::B::•<core::num>(0, s: #t1);
+}
+
+constants  {
+  #C1 = self::B<core::bool> {}
+  #C2 = <self::A<core::bool>>[#C1]
+}
+
+Extra constant evaluation status:
+Evaluated: VariableGet @ org-dartlang-testcase:///redirecting_constructors_declaration_order_3.dart:22:33 -> StringConstant("")
+Extra constant evaluation: evaluated: 12, effectively constant: 1
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///redirecting_constructors_declaration_order_3.dart:
+- B. (from org-dartlang-testcase:///redirecting_constructors_declaration_order_3.dart:17:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
diff --git a/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_3.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_3.dart.textual_outline.expect
new file mode 100644
index 0000000..61ae9b7
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_3.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+class C {
+  List<A<bool>> field;
+  C.named1({this.field = const [A.redir1(0, s: "")]});
+  C.named2({this.field = const [A.redir1(s: "", 0)]});
+}
+
+abstract class A<X> {
+  const factory A.redir1(int x, {required String s}) = B;
+  const factory A.redir2(int x, {required String s}) = B;
+}
+
+class B<Y> implements A<Y> {
+  const B(int x, {required String s});
+}
+
+test() {}
diff --git a/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_3.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_3.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..63f11e2
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_constructors_declaration_order_3.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+abstract class A<X> {
+  const factory A.redir1(int x, {required String s}) = B;
+  const factory A.redir2(int x, {required String s}) = B;
+}
+
+class B<Y> implements A<Y> {
+  const B(int x, {required String s});
+}
+
+class C {
+  C.named1({this.field = const [A.redir1(0, s: "")]});
+  C.named2({this.field = const [A.redir1(s: "", 0)]});
+  List<A<bool>> field;
+}
+
+test() {}
diff --git a/pkg/front_end/testcases/generic_metadata/alias_from_opt_in.dart.strong.expect b/pkg/front_end/testcases/generic_metadata/alias_from_opt_in.dart.strong.expect
index fb03960..adc5810 100644
--- a/pkg/front_end/testcases/generic_metadata/alias_from_opt_in.dart.strong.expect
+++ b/pkg/front_end/testcases/generic_metadata/alias_from_opt_in.dart.strong.expect
@@ -163,16 +163,16 @@
 //   new T7(0); // Error
 //       ^
 //
-// pkg/front_end/testcases/generic_metadata/alias_from_opt_in.dart:63:10: Error: The argument type 'int' can't be assigned to the parameter type 'List<void Function<T>(T)>'.
-//  - 'List' is from 'dart:core'.
-//   new T7(0); // Error
-//          ^
-//
 // pkg/front_end/testcases/generic_metadata/alias_from_opt_in.dart:59:7: Error: Generic function type 'void Function<T>(T)' inferred as a type argument.
 // Try providing a non-generic function type explicitly.
 //   new T4(); // Error
 //       ^
 //
+// pkg/front_end/testcases/generic_metadata/alias_from_opt_in.dart:63:10: Error: The argument type 'int' can't be assigned to the parameter type 'List<void Function<T>(T)>'.
+//  - 'List' is from 'dart:core'.
+//   new T7(0); // Error
+//          ^
+//
 // pkg/front_end/testcases/generic_metadata/alias_from_opt_in.dart:60:4: Error: Generic function type 'void Function<T>(T)' inferred as a type argument.
 // Try providing a non-generic function type explicitly.
 //   <T4>[]; // Error
diff --git a/pkg/front_end/testcases/generic_metadata/alias_from_opt_in.dart.strong.modular.expect b/pkg/front_end/testcases/generic_metadata/alias_from_opt_in.dart.strong.modular.expect
index fb03960..adc5810 100644
--- a/pkg/front_end/testcases/generic_metadata/alias_from_opt_in.dart.strong.modular.expect
+++ b/pkg/front_end/testcases/generic_metadata/alias_from_opt_in.dart.strong.modular.expect
@@ -163,16 +163,16 @@
 //   new T7(0); // Error
 //       ^
 //
-// pkg/front_end/testcases/generic_metadata/alias_from_opt_in.dart:63:10: Error: The argument type 'int' can't be assigned to the parameter type 'List<void Function<T>(T)>'.
-//  - 'List' is from 'dart:core'.
-//   new T7(0); // Error
-//          ^
-//
 // pkg/front_end/testcases/generic_metadata/alias_from_opt_in.dart:59:7: Error: Generic function type 'void Function<T>(T)' inferred as a type argument.
 // Try providing a non-generic function type explicitly.
 //   new T4(); // Error
 //       ^
 //
+// pkg/front_end/testcases/generic_metadata/alias_from_opt_in.dart:63:10: Error: The argument type 'int' can't be assigned to the parameter type 'List<void Function<T>(T)>'.
+//  - 'List' is from 'dart:core'.
+//   new T7(0); // Error
+//          ^
+//
 // pkg/front_end/testcases/generic_metadata/alias_from_opt_in.dart:60:4: Error: Generic function type 'void Function<T>(T)' inferred as a type argument.
 // Try providing a non-generic function type explicitly.
 //   <T4>[]; // Error
diff --git a/pkg/front_end/testcases/generic_metadata/alias_from_opt_in.dart.strong.transformed.expect b/pkg/front_end/testcases/generic_metadata/alias_from_opt_in.dart.strong.transformed.expect
index 6fe631c..9d18dd9 100644
--- a/pkg/front_end/testcases/generic_metadata/alias_from_opt_in.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/generic_metadata/alias_from_opt_in.dart.strong.transformed.expect
@@ -163,16 +163,16 @@
 //   new T7(0); // Error
 //       ^
 //
-// pkg/front_end/testcases/generic_metadata/alias_from_opt_in.dart:63:10: Error: The argument type 'int' can't be assigned to the parameter type 'List<void Function<T>(T)>'.
-//  - 'List' is from 'dart:core'.
-//   new T7(0); // Error
-//          ^
-//
 // pkg/front_end/testcases/generic_metadata/alias_from_opt_in.dart:59:7: Error: Generic function type 'void Function<T>(T)' inferred as a type argument.
 // Try providing a non-generic function type explicitly.
 //   new T4(); // Error
 //       ^
 //
+// pkg/front_end/testcases/generic_metadata/alias_from_opt_in.dart:63:10: Error: The argument type 'int' can't be assigned to the parameter type 'List<void Function<T>(T)>'.
+//  - 'List' is from 'dart:core'.
+//   new T7(0); // Error
+//          ^
+//
 // pkg/front_end/testcases/generic_metadata/alias_from_opt_in.dart:60:4: Error: Generic function type 'void Function<T>(T)' inferred as a type argument.
 // Try providing a non-generic function type explicitly.
 //   <T4>[]; // Error
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart.strong.expect
index 5dd8435..417b6fd 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart.strong.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart.strong.expect
@@ -2,26 +2,6 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:15:3: Error: Inferred type argument 'A<Object?>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'A'.
-//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart'.
-//  - 'Object' is from 'dart:core'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//   A(); // Error.
-//   ^
-// pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
-// class A<X extends A<X>> {}
-//         ^
-//
-// pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:17:3: Error: Inferred type argument 'A2<Object?>' doesn't conform to the bound 'A2<X>' of the type variable 'X' on 'A2'.
-//  - 'A2' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart'.
-//  - 'Object' is from 'dart:core'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//   A2(); // Error.
-//   ^
-// pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:8:10: Context: This is the type variable whose bound isn't conformed to.
-// class A2<X extends A2<X>> {
-//          ^
-//
 // pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:14:3: Error: Inferred type argument 'A<Object?>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
 //  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart'.
 //  - 'Object' is from 'dart:core'.
@@ -32,6 +12,16 @@
 // typedef B<X extends A<X>> = A<X>;
 //           ^
 //
+// pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:15:3: Error: Inferred type argument 'A<Object?>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'A'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   A(); // Error.
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends A<X>> {}
+//         ^
+//
 // pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:16:3: Error: Inferred type argument 'A2<Object?>' doesn't conform to the bound 'A2<X>' of the type variable 'X' on 'B2'.
 //  - 'A2' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart'.
 //  - 'Object' is from 'dart:core'.
@@ -52,6 +42,16 @@
 // class A2<X extends A2<X>> {
 //          ^
 //
+// pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:17:3: Error: Inferred type argument 'A2<Object?>' doesn't conform to the bound 'A2<X>' of the type variable 'X' on 'A2'.
+//  - 'A2' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   A2(); // Error.
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:8:10: Context: This is the type variable whose bound isn't conformed to.
+// class A2<X extends A2<X>> {
+//          ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart.strong.modular.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart.strong.modular.expect
index 5dd8435..417b6fd 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart.strong.modular.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart.strong.modular.expect
@@ -2,26 +2,6 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:15:3: Error: Inferred type argument 'A<Object?>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'A'.
-//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart'.
-//  - 'Object' is from 'dart:core'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//   A(); // Error.
-//   ^
-// pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
-// class A<X extends A<X>> {}
-//         ^
-//
-// pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:17:3: Error: Inferred type argument 'A2<Object?>' doesn't conform to the bound 'A2<X>' of the type variable 'X' on 'A2'.
-//  - 'A2' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart'.
-//  - 'Object' is from 'dart:core'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//   A2(); // Error.
-//   ^
-// pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:8:10: Context: This is the type variable whose bound isn't conformed to.
-// class A2<X extends A2<X>> {
-//          ^
-//
 // pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:14:3: Error: Inferred type argument 'A<Object?>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
 //  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart'.
 //  - 'Object' is from 'dart:core'.
@@ -32,6 +12,16 @@
 // typedef B<X extends A<X>> = A<X>;
 //           ^
 //
+// pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:15:3: Error: Inferred type argument 'A<Object?>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'A'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   A(); // Error.
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends A<X>> {}
+//         ^
+//
 // pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:16:3: Error: Inferred type argument 'A2<Object?>' doesn't conform to the bound 'A2<X>' of the type variable 'X' on 'B2'.
 //  - 'A2' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart'.
 //  - 'Object' is from 'dart:core'.
@@ -52,6 +42,16 @@
 // class A2<X extends A2<X>> {
 //          ^
 //
+// pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:17:3: Error: Inferred type argument 'A2<Object?>' doesn't conform to the bound 'A2<X>' of the type variable 'X' on 'A2'.
+//  - 'A2' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   A2(); // Error.
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:8:10: Context: This is the type variable whose bound isn't conformed to.
+// class A2<X extends A2<X>> {
+//          ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart.strong.transformed.expect
index 5dd8435..417b6fd 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart.strong.transformed.expect
@@ -2,26 +2,6 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:15:3: Error: Inferred type argument 'A<Object?>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'A'.
-//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart'.
-//  - 'Object' is from 'dart:core'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//   A(); // Error.
-//   ^
-// pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
-// class A<X extends A<X>> {}
-//         ^
-//
-// pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:17:3: Error: Inferred type argument 'A2<Object?>' doesn't conform to the bound 'A2<X>' of the type variable 'X' on 'A2'.
-//  - 'A2' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart'.
-//  - 'Object' is from 'dart:core'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//   A2(); // Error.
-//   ^
-// pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:8:10: Context: This is the type variable whose bound isn't conformed to.
-// class A2<X extends A2<X>> {
-//          ^
-//
 // pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:14:3: Error: Inferred type argument 'A<Object?>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
 //  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart'.
 //  - 'Object' is from 'dart:core'.
@@ -32,6 +12,16 @@
 // typedef B<X extends A<X>> = A<X>;
 //           ^
 //
+// pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:15:3: Error: Inferred type argument 'A<Object?>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'A'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   A(); // Error.
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends A<X>> {}
+//         ^
+//
 // pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:16:3: Error: Inferred type argument 'A2<Object?>' doesn't conform to the bound 'A2<X>' of the type variable 'X' on 'B2'.
 //  - 'A2' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart'.
 //  - 'Object' is from 'dart:core'.
@@ -52,6 +42,16 @@
 // class A2<X extends A2<X>> {
 //          ^
 //
+// pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:17:3: Error: Inferred type argument 'A2<Object?>' doesn't conform to the bound 'A2<X>' of the type variable 'X' on 'A2'.
+//  - 'A2' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   A2(); // Error.
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart:8:10: Context: This is the type variable whose bound isn't conformed to.
+// class A2<X extends A2<X>> {
+//          ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.strong.expect
index 0f569e6..d001566 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.strong.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.strong.expect
@@ -12,6 +12,16 @@
 // class A<X extends A<X>> {}
 //         ^
 //
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:33:9: Error: Inferred type argument 'A<Object?>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'C'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     new C();
+//         ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:14:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef C<X extends A<X>> = A<X>;
+//           ^
+//
 // pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:34:7: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'call'.
 //  - 'Object' is from 'dart:core'.
 //  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
@@ -76,16 +86,6 @@
 //     instance2(() => captureTypeArgument());
 //     ^
 //
-// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:33:9: Error: Inferred type argument 'A<Object?>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'C'.
-//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
-//  - 'Object' is from 'dart:core'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//     new C();
-//         ^
-// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:14:11: Context: This is the type variable whose bound isn't conformed to.
-// typedef C<X extends A<X>> = A<X>;
-//           ^
-//
 // pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:47:11: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'Subclass.instance1'.
 //  - 'Object' is from 'dart:core'.
 //  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.strong.modular.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.strong.modular.expect
index 0f569e6..d001566 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.strong.modular.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.strong.modular.expect
@@ -12,6 +12,16 @@
 // class A<X extends A<X>> {}
 //         ^
 //
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:33:9: Error: Inferred type argument 'A<Object?>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'C'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     new C();
+//         ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:14:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef C<X extends A<X>> = A<X>;
+//           ^
+//
 // pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:34:7: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'call'.
 //  - 'Object' is from 'dart:core'.
 //  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
@@ -76,16 +86,6 @@
 //     instance2(() => captureTypeArgument());
 //     ^
 //
-// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:33:9: Error: Inferred type argument 'A<Object?>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'C'.
-//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
-//  - 'Object' is from 'dart:core'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//     new C();
-//         ^
-// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:14:11: Context: This is the type variable whose bound isn't conformed to.
-// typedef C<X extends A<X>> = A<X>;
-//           ^
-//
 // pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:47:11: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'Subclass.instance1'.
 //  - 'Object' is from 'dart:core'.
 //  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.strong.transformed.expect
index 0f569e6..d001566 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.strong.transformed.expect
@@ -12,6 +12,16 @@
 // class A<X extends A<X>> {}
 //         ^
 //
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:33:9: Error: Inferred type argument 'A<Object?>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'C'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     new C();
+//         ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:14:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef C<X extends A<X>> = A<X>;
+//           ^
+//
 // pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:34:7: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'call'.
 //  - 'Object' is from 'dart:core'.
 //  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
@@ -76,16 +86,6 @@
 //     instance2(() => captureTypeArgument());
 //     ^
 //
-// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:33:9: Error: Inferred type argument 'A<Object?>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'C'.
-//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
-//  - 'Object' is from 'dart:core'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//     new C();
-//         ^
-// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:14:11: Context: This is the type variable whose bound isn't conformed to.
-// typedef C<X extends A<X>> = A<X>;
-//           ^
-//
 // pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:47:11: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'Subclass.instance1'.
 //  - 'Object' is from 'dart:core'.
 //  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.strong.expect
index 47a40ba..849cda5 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.strong.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.strong.expect
@@ -2,6 +2,16 @@
 //
 // Problems in library:
 //
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:20:3: Error: Inferred type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   A(); // Error.
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:16:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends G<C<X>>> = C<X>;
+//           ^
+//
 // pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:21:5: Error: Inferred type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
 //  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
 //  - 'Object' is from 'dart:core'.
@@ -12,6 +22,16 @@
 // typedef A<X extends G<C<X>>> = C<X>;
 //           ^
 //
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:22:5: Error: Inferred type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   A.bar(); // Error.
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:16:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends G<C<X>>> = C<X>;
+//           ^
+//
 // pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:23:3: Error: Inferred type argument 'D<Object?> Function(D<Never>)' doesn't conform to the bound 'D<X> Function(D<X>)' of the type variable 'X' on 'B'.
 //  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
 //  - 'Object' is from 'dart:core'.
@@ -22,26 +42,6 @@
 // typedef B<X extends G<D<X>>> = D<X>;
 //           ^
 //
-// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:20:3: Error: Inferred type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
-//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
-//  - 'Object' is from 'dart:core'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//   A(); // Error.
-//   ^
-// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:16:11: Context: This is the type variable whose bound isn't conformed to.
-// typedef A<X extends G<C<X>>> = C<X>;
-//           ^
-//
-// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:22:5: Error: Inferred type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
-//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
-//  - 'Object' is from 'dart:core'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//   A.bar(); // Error.
-//     ^
-// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:16:11: Context: This is the type variable whose bound isn't conformed to.
-// typedef A<X extends G<C<X>>> = C<X>;
-//           ^
-//
 // pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:24:5: Error: Inferred type argument 'D<Object?> Function(D<Never>)' doesn't conform to the bound 'D<X> Function(D<X>)' of the type variable 'X' on 'B'.
 //  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
 //  - 'Object' is from 'dart:core'.
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.strong.modular.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.strong.modular.expect
index 47a40ba..849cda5 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.strong.modular.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.strong.modular.expect
@@ -2,6 +2,16 @@
 //
 // Problems in library:
 //
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:20:3: Error: Inferred type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   A(); // Error.
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:16:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends G<C<X>>> = C<X>;
+//           ^
+//
 // pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:21:5: Error: Inferred type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
 //  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
 //  - 'Object' is from 'dart:core'.
@@ -12,6 +22,16 @@
 // typedef A<X extends G<C<X>>> = C<X>;
 //           ^
 //
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:22:5: Error: Inferred type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   A.bar(); // Error.
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:16:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends G<C<X>>> = C<X>;
+//           ^
+//
 // pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:23:3: Error: Inferred type argument 'D<Object?> Function(D<Never>)' doesn't conform to the bound 'D<X> Function(D<X>)' of the type variable 'X' on 'B'.
 //  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
 //  - 'Object' is from 'dart:core'.
@@ -22,26 +42,6 @@
 // typedef B<X extends G<D<X>>> = D<X>;
 //           ^
 //
-// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:20:3: Error: Inferred type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
-//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
-//  - 'Object' is from 'dart:core'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//   A(); // Error.
-//   ^
-// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:16:11: Context: This is the type variable whose bound isn't conformed to.
-// typedef A<X extends G<C<X>>> = C<X>;
-//           ^
-//
-// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:22:5: Error: Inferred type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
-//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
-//  - 'Object' is from 'dart:core'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//   A.bar(); // Error.
-//     ^
-// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:16:11: Context: This is the type variable whose bound isn't conformed to.
-// typedef A<X extends G<C<X>>> = C<X>;
-//           ^
-//
 // pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:24:5: Error: Inferred type argument 'D<Object?> Function(D<Never>)' doesn't conform to the bound 'D<X> Function(D<X>)' of the type variable 'X' on 'B'.
 //  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
 //  - 'Object' is from 'dart:core'.
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.strong.transformed.expect
index 47a40ba..849cda5 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.strong.transformed.expect
@@ -2,6 +2,16 @@
 //
 // Problems in library:
 //
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:20:3: Error: Inferred type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   A(); // Error.
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:16:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends G<C<X>>> = C<X>;
+//           ^
+//
 // pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:21:5: Error: Inferred type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
 //  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
 //  - 'Object' is from 'dart:core'.
@@ -12,6 +22,16 @@
 // typedef A<X extends G<C<X>>> = C<X>;
 //           ^
 //
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:22:5: Error: Inferred type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   A.bar(); // Error.
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:16:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends G<C<X>>> = C<X>;
+//           ^
+//
 // pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:23:3: Error: Inferred type argument 'D<Object?> Function(D<Never>)' doesn't conform to the bound 'D<X> Function(D<X>)' of the type variable 'X' on 'B'.
 //  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
 //  - 'Object' is from 'dart:core'.
@@ -22,26 +42,6 @@
 // typedef B<X extends G<D<X>>> = D<X>;
 //           ^
 //
-// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:20:3: Error: Inferred type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
-//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
-//  - 'Object' is from 'dart:core'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//   A(); // Error.
-//   ^
-// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:16:11: Context: This is the type variable whose bound isn't conformed to.
-// typedef A<X extends G<C<X>>> = C<X>;
-//           ^
-//
-// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:22:5: Error: Inferred type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
-//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
-//  - 'Object' is from 'dart:core'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//   A.bar(); // Error.
-//     ^
-// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:16:11: Context: This is the type variable whose bound isn't conformed to.
-// typedef A<X extends G<C<X>>> = C<X>;
-//           ^
-//
 // pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:24:5: Error: Inferred type argument 'D<Object?> Function(D<Never>)' doesn't conform to the bound 'D<X> Function(D<X>)' of the type variable 'X' on 'B'.
 //  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
 //  - 'Object' is from 'dart:core'.
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index be6a69d..a1234c6 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -79,6 +79,7 @@
 regress/issue_39682: semiFuzzFailureOnForceRebuildBodies # has private method
 dart2wasm/inference_update_2/issue52452: semiFuzzFailureOnForceRebuildBodies # private fields in class.
 records/nullable_access_extension: semiFuzzFailureOnForceRebuildBodies # unnamed extension
+general/constructor_inference_interdependence: semiFuzzFailureOnForceRebuildBodies # sealed class ending up in another library.
 
 # FUZZ FRAMEWORK FAILURES
 general/script_tag_in_part_file: SemiFuzzFailure # `#!/usr/bin/env dart` goes away
diff --git a/tools/VERSION b/tools/VERSION
index 4f2a1a3..6f7908c 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 3
 MINOR 6
 PATCH 0
-PRERELEASE 105
+PRERELEASE 106
 PRERELEASE_PATCH 0