[cfe] Process invocations eagerly
Some invocation nodes, such as redirecting factory invocations,
type-aliased constructor invocations, and type aliased factory
invocations, were unaliased and resolved via lists of delayed
processing actions. That was due to dependencies of the processing
actions on each other.
This CL untangles the dependencies and processes the invocations
eagerly. Namely, the redirecting factory constructors are processed
before all other nodes that may require unaliasing and resolving. The
eager processing of nodes eliminates the need for fragile filtering of
the nodes that may require post-processing.
Change-Id: I3e6971515a974c01eced31aa68bf72399dcfa8b8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/372280
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
diff --git a/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart b/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
index 917f6ca..de55563 100644
--- a/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
@@ -21,7 +21,6 @@
import '../source/source_factory_builder.dart';
import '../source/source_field_builder.dart';
import '../source/source_library_builder.dart';
-import '../util/helpers.dart' show DelayedActionPerformer;
import 'builder.dart';
import 'constructor_builder.dart';
import 'declaration_builders.dart';
@@ -271,8 +270,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 =
@@ -294,9 +292,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/fasta/builder/metadata_builder.dart b/pkg/front_end/lib/src/fasta/builder/metadata_builder.dart
index def4470..f54d277 100644
--- a/pkg/front_end/lib/src/fasta/builder/metadata_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/metadata_builder.dart
@@ -105,7 +105,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/fasta/builder/type_variable_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
index de6c07f..9e43a05 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
@@ -391,7 +391,6 @@
SourceLibraryBuilder libraryBuilder,
BodyBuilderContext bodyBuilderContext,
ClassHierarchy classHierarchy,
- List<DelayedActionPerformer> delayedActionPerformers,
Scope scope) {
MetadataBuilder.buildAnnotations(parameter, metadata, bodyBuilderContext,
libraryBuilder, fileUri!, scope);
diff --git a/pkg/front_end/lib/src/fasta/kernel/benchmarker.dart b/pkg/front_end/lib/src/fasta/kernel/benchmarker.dart
index 4352c4f..8228c13 100644
--- a/pkg/front_end/lib/src/fasta/kernel/benchmarker.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/benchmarker.dart
@@ -186,6 +186,7 @@
outline_computeHierarchy,
outline_computeShowHideElements,
outline_installTypedefTearOffs,
+ outline_performRedirectingFactoryInference,
outline_performTopLevelInference,
outline_checkOverrides,
outline_checkAbstractMembers,
@@ -276,7 +277,6 @@
inferRedirectingFactoryTypeArguments,
buildOutlineExpressions,
- delayedActionPerformer,
computeMacroApplications_macroExecutorProvider,
macroApplications_macroExecutorLoadMacro,
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 7a29846..8fe3a22 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -122,7 +122,7 @@
}
class BodyBuilder extends StackListenerImpl
- implements ExpressionGeneratorHelper, DelayedActionPerformer {
+ implements ExpressionGeneratorHelper {
@override
final Forest forest;
@@ -242,89 +242,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;
@@ -342,10 +259,6 @@
int functionNestingLevel = 0;
- int _inBodyCount = 0;
-
- bool get _inBody => _inBodyCount > 0;
-
Statement? problemInLoopOrSwitch;
Scope? switchScope;
@@ -365,41 +278,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;
@@ -506,9 +384,6 @@
void enterLocalScope(Scope localScope) {
push(scope);
scope = localScope;
- if (scope.kind == ScopeKind.functionBody) {
- _inBodyCount++;
- }
assert(checkState(null, [
ValueKinds.Scope,
]));
@@ -518,9 +393,6 @@
{required String debugName, required ScopeKind kind}) {
push(scope);
scope = scope.createNestedScope(debugName: debugName, kind: kind);
- if (kind == ScopeKind.functionBody) {
- _inBodyCount++;
- }
assert(checkState(null, [
ValueKinds.Scope,
]));
@@ -545,9 +417,6 @@
declaredInCurrentGuard = null;
}
}
- if (scope.kind == ScopeKind.functionBody) {
- _inBodyCount--;
- }
scope = pop() as Scope;
}
@@ -907,7 +776,6 @@
super.push(constantContext);
constantContext = ConstantContext.inferred;
assert(checkState(token, [ValueKinds.ConstantContext]));
- _insideMetadataParsing = true;
}
@override
@@ -982,7 +850,6 @@
}
constantContext = savedConstantContext;
}
- _insideMetadataParsing = false;
assert(checkState(beginToken, [ValueKinds.Expression]));
}
@@ -1066,21 +933,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;
@@ -1108,7 +961,7 @@
}
pop(); // Annotations.
- performBacklogComputations(allowFurtherDelays: false);
+ performBacklogComputations();
assert(stack.length == 0);
}
@@ -1117,39 +970,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,
- "Body builder has delayed actions that cannot be performed: "
- "${[
- ...delayedRedirectingFactoryInvocations,
- ...delayedTypeAliasedFactoryInvocations,
- ...delayedTypeAliasedConstructorInvocations,
- ]}");
- delayedActionPerformers?.add(this);
- }
}
void finishRedirectingFactoryBody() {
- performBacklogComputations(allowFurtherDelays: false);
+ performBacklogComputations();
}
@override
@@ -1453,7 +1280,7 @@
_context.setBody(body);
}
- performBacklogComputations(allowFurtherDelays: false);
+ performBacklogComputations();
}
void checkAsyncReturnType(AsyncMarker asyncModifier, DartType returnType,
@@ -1569,7 +1396,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;
@@ -1616,188 +1444,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),
- "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),
- "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) {
- 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) {
- 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) {
- 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() {
@@ -1849,13 +1538,12 @@
} else {
temporaryParent = new ListLiteral(expressions);
}
- performBacklogComputations(allowFurtherDelays: false);
+ performBacklogComputations();
return temporaryParent != null ? temporaryParent.expressions : expressions;
}
Expression parseSingleExpression(
Parser parser, Token token, FunctionNode parameters) {
- assert(redirectingFactoryInvocations.isEmpty);
int fileOffset = offsetForToken(token);
List<NominalVariableBuilder>? typeParameterBuilders;
for (TypeParameter typeParameter in parameters.typeParameters) {
@@ -1926,7 +1614,7 @@
"Previously implicit assumption about inferFunctionBody "
"not returning anything different.");
- performBacklogComputations(allowFurtherDelays: false);
+ performBacklogComputations();
return fakeReturn.expression!;
}
@@ -5577,7 +5265,6 @@
super.push(constantContext);
_insideOfFormalParameterType = false;
constantContext = ConstantContext.required;
- _defaultValueNestingLevel++;
}
@override
@@ -5586,7 +5273,6 @@
Object? defaultValueExpression = pop();
constantContext = pop() as ConstantContext;
push(defaultValueExpression);
- _defaultValueNestingLevel--;
}
@override
@@ -6062,17 +5748,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 {
@@ -6103,9 +5784,6 @@
libraryBuilder.checkBoundsInFactoryInvocation(
factoryConstructorInvocation, typeEnvironment, uri,
inferred: !hasExplicitTypeArguments(arguments));
- if (_createdStaticInvocationsNeedPostProcessing) {
- redirectingFactoryInvocations.add(factoryConstructorInvocation);
- }
node = factoryConstructorInvocation;
} else {
TypeAliasedFactoryInvocation typeAliasedFactoryInvocation =
@@ -6115,9 +5793,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;
@@ -10220,14 +9895,12 @@
node.target, clone(node.arguments),
isConst: node.isConst)
..hasBeenInferred = node.hasBeenInferred;
- bodyBuilder.redirectingFactoryInvocations.add(result);
return result;
} else if (node is TypeAliasedFactoryInvocation) {
TypeAliasedFactoryInvocation result = new TypeAliasedFactoryInvocation(
node.typeAliasBuilder, node.target, clone(node.arguments),
isConst: node.isConst)
..hasBeenInferred = node.hasBeenInferred;
- bodyBuilder.typeAliasedFactoryInvocations.add(result);
return result;
}
return super.visitStaticInvocation(node);
@@ -10241,7 +9914,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/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 77ec6ea..faf23a3 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -542,6 +542,13 @@
?.enterPhase(BenchmarkPhases.outline_computeFieldPromotability);
loader.computeFieldPromotability();
+ benchmarker?.enterPhase(
+ BenchmarkPhases.outline_performRedirectingFactoryInference);
+ // TODO(johnniwinther): Add an interface for registering delayed actions.
+ List<DelayedDefaultValueCloner> delayedDefaultValueCloners = [];
+ loader.inferRedirectingFactories(
+ loader.hierarchy, delayedDefaultValueCloners);
+
benchmarker?.enterPhase(BenchmarkPhases.outline_performTopLevelInference);
loader.performTopLevelInference(sortedSourceClassBuilders);
@@ -555,8 +562,6 @@
loader.checkMixins(sortedSourceClassBuilders);
benchmarker?.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/fasta/scope.dart b/pkg/front_end/lib/src/fasta/scope.dart
index ae10670..e636bab 100644
--- a/pkg/front_end/lib/src/fasta/scope.dart
+++ b/pkg/front_end/lib/src/fasta/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;
enum ScopeKind {
/// Scope of pattern switch-case statements
@@ -1001,9 +1000,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/fasta/source/source_builder_mixins.dart b/pkg/front_end/lib/src/fasta/source/source_builder_mixins.dart
index 3a81867..729abfc 100644
--- a/pkg/front_end/lib/src/fasta/source/source_builder_mixins.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_builder_mixins.dart
@@ -20,7 +20,6 @@
import '../messages.dart';
import '../problems.dart';
import '../scope.dart';
-import '../util/helpers.dart';
import 'source_constructor_builder.dart';
import 'source_field_builder.dart';
import 'source_library_builder.dart';
@@ -147,9 +146,7 @@
required bool inMetadata,
required bool inConstFields});
- void buildOutlineExpressions(
- ClassHierarchy classHierarchy,
- List<DelayedActionPerformer> delayedActionPerformers,
+ void buildOutlineExpressions(ClassHierarchy classHierarchy,
List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
MetadataBuilder.buildAnnotations(
annotatable,
@@ -170,7 +167,6 @@
inMetadata: true,
inConstFields: false),
classHierarchy,
- delayedActionPerformers,
scope.parent!);
}
}
@@ -178,8 +174,8 @@
Iterator<SourceMemberBuilder> iterator = scope.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/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index fd67ab7..f16c8c6 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -43,7 +43,6 @@
import '../kernel/utils.dart' show compareProcedures;
import '../problems.dart' show unexpected, unhandled, unimplemented;
import '../scope.dart';
-import '../util/helpers.dart';
import 'class_declaration.dart';
import 'source_builder_mixins.dart';
import 'source_constructor_builder.dart';
@@ -344,14 +343,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(
@@ -374,7 +371,6 @@
inMetadata: true,
inConstFields: false),
classHierarchy,
- delayedActionPerformers,
scope.parent!);
}
}
diff --git a/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart b/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
index 098a07b..0f02681 100644
--- a/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
@@ -49,7 +49,6 @@
import '../source/source_member_builder.dart';
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_extension_type_declaration_builder.dart';
@@ -299,9 +298,7 @@
}
void _buildConstructorForOutline(
- Token? beginInitializers,
- List<DelayedActionPerformer> delayedActionPerformers,
- Scope declarationScope) {
+ Token? beginInitializers, Scope declarationScope) {
if (beginInitializers != null) {
final Scope? formalParameterScope;
if (isConst) {
@@ -327,9 +324,7 @@
}
bodyBuilder.parseInitializers(beginInitializers,
doFinishConstructor: isConst);
- bodyBuilder.performBacklogComputations(
- delayedActionPerformers: delayedActionPerformers,
- allowFurtherDelays: false);
+ bodyBuilder.performBacklogComputations();
}
}
@@ -800,24 +795,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) {
@@ -1044,9 +1035,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].
@@ -1054,8 +1043,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;
@@ -1198,20 +1187,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.
Scope typeParameterScope =
computeTypeParameterScope(extensionTypeDeclarationBuilder.scope);
- _buildConstructorForOutline(
- beginInitializers, delayedActionPerformers, typeParameterScope);
+ _buildConstructorForOutline(beginInitializers, typeParameterScope);
_buildBody();
}
beginInitializers = null;
diff --git a/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart b/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
index 92d88e3..8df142e 100644
--- a/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
@@ -53,7 +53,6 @@
import '../scope.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';
@@ -81,8 +80,6 @@
final Set<SourceFieldBuilder> _builtElements =
new Set<SourceFieldBuilder>.identity();
- final List<DelayedActionPerformer> _delayedActionPerformers = [];
-
SourceEnumBuilder.internal(
List<MetadataBuilder>? metadata,
String name,
@@ -745,9 +742,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);
@@ -821,9 +816,7 @@
}
@override
- void buildOutlineExpressions(
- ClassHierarchy classHierarchy,
- List<DelayedActionPerformer> delayedActionPerformers,
+ void buildOutlineExpressions(ClassHierarchy classHierarchy,
List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
List<Expression> values = <Expression>[];
if (enumConstantInfos != null) {
@@ -850,8 +843,6 @@
elementBuilder.type.registerInferredType(
buildElement(elementBuilder, classHierarchy.coreTypes));
}
- delayedActionPerformers.addAll(_delayedActionPerformers);
- _delayedActionPerformers.clear();
SourceProcedureBuilder toStringBuilder =
firstMemberNamed("_enumToString") as SourceProcedureBuilder;
@@ -887,8 +878,7 @@
]));
}
- super.buildOutlineExpressions(
- classHierarchy, delayedActionPerformers, delayedDefaultValueCloners);
+ super.buildOutlineExpressions(classHierarchy, delayedDefaultValueCloners);
}
}
diff --git a/pkg/front_end/lib/src/fasta/source/source_extension_type_declaration_builder.dart b/pkg/front_end/lib/src/fasta/source/source_extension_type_declaration_builder.dart
index 1498e7d..7c431a4 100644
--- a/pkg/front_end/lib/src/fasta/source/source_extension_type_declaration_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_extension_type_declaration_builder.dart
@@ -28,7 +28,6 @@
import '../problems.dart';
import '../scope.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';
@@ -557,18 +556,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/fasta/source/source_factory_builder.dart b/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart
index f4e4d35..43fec20 100644
--- a/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart
@@ -13,6 +13,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/fasta_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';
@@ -197,16 +197,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;
}
@@ -475,20 +472,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)) {
@@ -507,8 +505,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;
@@ -518,6 +516,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/fasta/source/source_field_builder.dart b/pkg/front_end/lib/src/fasta/source/source_field_builder.dart
index 353926e..a899825 100644
--- a/pkg/front_end/lib/src/fasta/source/source_field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_field_builder.dart
@@ -38,7 +38,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';
@@ -447,9 +446,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(
@@ -490,9 +487,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/fasta/source/source_function_builder.dart b/pkg/front_end/lib/src/fasta/source/source_function_builder.dart
index 7ef9ebd..7f1d093 100644
--- a/pkg/front_end/lib/src/fasta/source/source_function_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_function_builder.dart
@@ -33,7 +33,6 @@
import '../source/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';
@@ -476,9 +475,7 @@
}
@override
- void buildOutlineExpressions(
- ClassHierarchy classHierarchy,
- List<DelayedActionPerformer> delayedActionPerformers,
+ void buildOutlineExpressions(ClassHierarchy classHierarchy,
List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
if (!hasBuiltOutlineExpressions) {
DeclarationBuilder? classOrExtensionBuilder =
@@ -509,7 +506,6 @@
inMetadata: true,
inConstFields: false),
classHierarchy,
- delayedActionPerformers,
computeTypeParameterScope(parentScope));
}
}
@@ -520,8 +516,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/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 8cce766..8d8de9d 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -103,7 +103,6 @@
import '../problems.dart' show unexpected, unhandled;
import '../scope.dart';
import '../uris.dart';
-import '../util/helpers.dart';
import 'class_declaration.dart';
import 'name_scheme.dart';
import 'offset_map.dart';
@@ -1963,6 +1962,8 @@
procedureNameScheme,
nativeMethodName,
redirectionTarget);
+ (sourceLibraryBuilder.redirectingFactoryBuilders ??= [])
+ .add(procedureBuilder as RedirectingFactoryBuilder);
} else {
procedureBuilder = new SourceFactoryBuilder(
metadata,
@@ -2777,6 +2778,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;
+
SourceLibraryBuilder.internal(
SourceLoader loader,
Uri importUri,
@@ -4013,16 +4021,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);
}
}
@@ -4042,20 +4048,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/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 07d4134..dad7dbf 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -77,7 +77,6 @@
import '../type_inference/type_inferrer.dart';
import '../uri_offset.dart';
import '../uris.dart';
-import '../util/helpers.dart';
import 'diet_listener.dart' show DietListener;
import 'diet_parser.dart' show DietParser, useImplicitCreationExpressionInCfe;
import 'name_scheme.dart';
@@ -87,6 +86,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,
@@ -2771,21 +2771,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
- ?.beginSubdivide(BenchmarkSubdivides.delayedActionPerformer);
- for (DelayedActionPerformer delayedActionPerformer
- in delayedActionPerformers) {
- delayedActionPerformer.performDelayedActions(allowFurtherDelays: false);
- }
- target.benchmarker?.endSubdivide();
- ticker.logMs("Build outline expressions");
}
void buildClassHierarchy(
@@ -2813,7 +2802,15 @@
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
@@ -2821,6 +2818,30 @@
typeInferenceEngine.prepareTopLevel(coreTypes, hierarchy);
membersBuilder.computeTypes();
+ // 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) {
List<InferableType> inferableTypes = [];
for (SourceLibraryBuilder libraryBuilder in sourceLibraryBuilders) {
libraryBuilder.collectInferableTypes(inferableTypes);
diff --git a/pkg/front_end/lib/src/fasta/source/source_member_builder.dart b/pkg/front_end/lib/src/fasta/source/source_member_builder.dart
index 8b6dbc1..2b13dc6 100644
--- a/pkg/front_end/lib/src/fasta/source/source_member_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_member_builder.dart
@@ -19,7 +19,6 @@
import '../source/source_library_builder.dart';
import '../type_inference/type_inference_engine.dart'
show InferenceDataForTesting;
-import '../util/helpers.dart' show DelayedActionPerformer;
import 'source_class_builder.dart';
typedef BuildNodesCallback = void Function(
@@ -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.
@@ -159,9 +156,7 @@
ProcedureKind? get kind => unsupported("kind", charOffset, fileUri);
@override
- void buildOutlineExpressions(
- ClassHierarchy classHierarchy,
- List<DelayedActionPerformer> delayedActionPerformers,
+ void buildOutlineExpressions(ClassHierarchy classHierarchy,
List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {}
@override
diff --git a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
index 5b8e423..5e17538 100644
--- a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
@@ -25,7 +25,6 @@
import '../kernel/kernel_helper.dart';
import '../problems.dart' show unhandled;
import '../scope.dart';
-import '../util/helpers.dart';
import 'source_library_builder.dart' show SourceLibraryBuilder;
class SourceTypeAliasBuilder extends TypeAliasBuilderImpl {
@@ -327,9 +326,7 @@
inConstFields: inConstFields);
}
- void buildOutlineExpressions(
- ClassHierarchy classHierarchy,
- List<DelayedActionPerformer> delayedActionPerformers,
+ void buildOutlineExpressions(ClassHierarchy classHierarchy,
List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
MetadataBuilder.buildAnnotations(
typedef,
@@ -350,7 +347,6 @@
inMetadata: true,
inConstFields: false),
classHierarchy,
- delayedActionPerformers,
computeTypeParameterScope(libraryBuilder.scope));
}
}
diff --git a/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart b/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart
index b6e0deb..9b93bbb 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart
@@ -5,6 +5,7 @@
import 'package:kernel/ast.dart';
import '../codes/fasta_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/fasta/type_inference/inference_visitor.dart b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart
index a92b8d6..44b3b5a 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart
@@ -1355,15 +1355,17 @@
node.fileOffset, functionType, node.arguments as ArgumentsImpl,
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].
@@ -1416,10 +1418,13 @@
node.fileOffset, calleeType, node.arguments as ArgumentsImpl,
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].
@@ -1473,10 +1478,13 @@
InvocationInferenceResult result = inferInvocation(this, typeContext,
node.fileOffset, calleeType, 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/fasta/util/helpers.dart b/pkg/front_end/lib/src/fasta/util/helpers.dart
index d7714ef..9da4e14 100644
--- a/pkg/front_end/lib/src/fasta/util/helpers.dart
+++ b/pkg/front_end/lib/src/fasta/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 f2438be..2bdef06 100644
--- a/pkg/front_end/test/coverage_suite_expected.dart
+++ b/pkg/front_end/test/coverage_suite_expected.dart
@@ -421,15 +421,15 @@
hitCount: 0,
missCount: 128,
),
- // 92.14792978694895%.
+ // 92.06240591213904%.
"package:front_end/src/fasta/kernel/body_builder.dart": (
- hitCount: 6877,
- missCount: 586,
+ hitCount: 6727,
+ missCount: 580,
),
- // 70.40816326530613%.
+ // 69.18367346938776%.
"package:front_end/src/fasta/kernel/body_builder_context.dart": (
- hitCount: 345,
- missCount: 145,
+ hitCount: 339,
+ missCount: 151,
),
// 36.44736842105264%.
"package:front_end/src/fasta/kernel/collections.dart": (
@@ -541,10 +541,10 @@
hitCount: 1,
missCount: 33,
),
- // 46.484375%.
+ // 46.09375%.
"package:front_end/src/fasta/kernel/internal_ast.dart": (
- hitCount: 595,
- missCount: 685,
+ hitCount: 590,
+ missCount: 690,
),
// 74.13793103448276%.
"package:front_end/src/fasta/kernel/invalid_type.dart": (
@@ -561,10 +561,10 @@
hitCount: 285,
missCount: 3,
),
- // 81.22605363984674%.
+ // 81.23569794050344%.
"package:front_end/src/fasta/kernel/kernel_target.dart": (
- hitCount: 1060,
- missCount: 245,
+ hitCount: 1065,
+ missCount: 246,
),
// 61.111111111111114%.
"package:front_end/src/fasta/kernel/kernel_variable_builder.dart": (
@@ -706,9 +706,9 @@
hitCount: 118,
missCount: 6,
),
- // 93.57084357084358%.
+ // 93.57873210633947%.
"package:front_end/src/fasta/source/outline_builder.dart": (
- hitCount: 2285,
+ hitCount: 2288,
missCount: 157,
),
// 94.44444444444444%.
@@ -731,9 +731,9 @@
hitCount: 858,
missCount: 68,
),
- // 95.73560767590618%.
+ // 95.6896551724138%.
"package:front_end/src/fasta/source/source_enum_builder.dart": (
- hitCount: 449,
+ hitCount: 444,
missCount: 20,
),
// 61.261261261261254%.
@@ -747,9 +747,9 @@
hitCount: 425,
missCount: 79,
),
- // 92.22222222222223%.
+ // 92.3076923076923%.
"package:front_end/src/fasta/source/source_factory_builder.dart": (
- hitCount: 581,
+ hitCount: 588,
missCount: 49,
),
// 89.94668697638994%.
@@ -757,20 +757,20 @@
hitCount: 1181,
missCount: 132,
),
- // 89.29663608562691%.
+ // 89.32926829268293%.
"package:front_end/src/fasta/source/source_function_builder.dart": (
- hitCount: 292,
+ hitCount: 293,
missCount: 35,
),
- // 85.4483096521313%.
+ // 85.38745387453875%.
"package:front_end/src/fasta/source/source_library_builder.dart": (
- hitCount: 3488,
+ hitCount: 3471,
missCount: 594,
),
- // 81.8988464951198%.
+ // 81.96357174589072%.
"package:front_end/src/fasta/source/source_loader.dart": (
- hitCount: 1846,
- missCount: 408,
+ hitCount: 1845,
+ missCount: 406,
),
// 40.32258064516129%.
"package:front_end/src/fasta/source/source_member_builder.dart": (
@@ -827,9 +827,9 @@
hitCount: 166,
missCount: 29,
),
- // 90.37792719684674%.
+ // 90.39018177607966%.
"package:front_end/src/fasta/type_inference/inference_visitor.dart": (
- hitCount: 7796,
+ hitCount: 7807,
missCount: 830,
),
// 85.96491228070175%.
@@ -877,10 +877,10 @@
hitCount: 484,
missCount: 56,
),
- // 54.037267080745345%.
+ // 59.006211180124225%.
"package:front_end/src/fasta/type_inference/type_inferrer.dart": (
- hitCount: 87,
- missCount: 74,
+ hitCount: 95,
+ missCount: 66,
),
// 36.666666666666664%.
"package:front_end/src/fasta/type_inference/type_schema.dart": (
@@ -932,10 +932,10 @@
hitCount: 78,
missCount: 1316,
),
- // 20.424013434089%.
+ // 20.40687919463087%.
"package:front_end/src/fasta/util/parser_ast_helper.dart": (
hitCount: 973,
- missCount: 3791,
+ missCount: 3795,
),
// 86.54205607476636%.
"package:front_end/src/fasta/util/textual_outline.dart": (
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/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'.