Version 2.18.0-184.0.dev
Merge commit '56b013fed852c779e06338cd4cc9c3cfe8c4d6d0' into 'dev'
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index 4549c6b..d52aaff 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -48,18 +48,6 @@
Class? mapEntryClass;
- // Stores the offset of the map entry found by inferMapEntry.
- int? mapEntryOffset = null;
-
- // Stores the offset of the map spread found by inferMapEntry.
- int? mapSpreadOffset = null;
-
- // Stores the offset of the iterable spread found by inferMapEntry.
- int? iterableSpreadOffset = null;
-
- // Stores the type of the iterable spread found by inferMapEntry.
- DartType? iterableSpreadType = null;
-
InferenceVisitor(this.inferrer);
/// Computes uri and offset for [node] for internal errors in a way that is
@@ -2174,7 +2162,8 @@
Map<TreeNode, DartType> inferredSpreadTypes,
Map<Expression, DartType> inferredConditionTypes,
bool inferenceNeeded,
- bool typeChecksNeeded) {
+ bool typeChecksNeeded,
+ _MapLiteralEntryOffsets offsets) {
if (entry is SpreadMapEntry) {
ExpressionInferenceResult spreadResult = inferrer.inferExpression(
entry.expression, spreadContext, inferenceNeeded || typeChecksNeeded,
@@ -2230,7 +2219,7 @@
// Don't report the error here, it might be an ambiguous Set. The
// error is reported in checkMapEntry if it's disambiguated as map.
- iterableSpreadType = spreadType;
+ offsets.iterableSpreadType = spreadType;
} else {
Expression receiver = entry.expression;
Expression problem = inferrer.helper.buildProblem(
@@ -2389,10 +2378,10 @@
inferrer.coreTypes.iterableRawType(inferrer.libraryBuilder.nullable),
SubtypeCheckMode.withNullabilities);
if (isMap && !isIterable) {
- mapSpreadOffset = entry.fileOffset;
+ offsets.mapSpreadOffset = entry.fileOffset;
}
if (!isMap && isIterable) {
- iterableSpreadOffset = entry.expression.fileOffset;
+ offsets.iterableSpreadOffset = entry.expression.fileOffset;
}
return replacement;
@@ -2421,9 +2410,9 @@
inferredSpreadTypes,
inferredConditionTypes,
inferenceNeeded,
- typeChecksNeeded);
+ typeChecksNeeded,
+ offsets);
entry.then = then..parent = entry;
- MapLiteralEntry otherwise;
if (entry.otherwise != null) {
inferrer.flowAnalysis.ifStatement_elseBegin();
// We need to modify the actual types added in the recursive call to
@@ -2431,7 +2420,7 @@
DartType? actualValueType = actualTypes.removeLast();
DartType? actualKeyType = actualTypes.removeLast();
DartType actualTypeForSet = actualTypesForSet.removeLast();
- otherwise = inferMapEntry(
+ MapLiteralEntry otherwise = inferMapEntry(
entry.otherwise!,
entry,
inferredKeyType,
@@ -2442,7 +2431,8 @@
inferredSpreadTypes,
inferredConditionTypes,
inferenceNeeded,
- typeChecksNeeded);
+ typeChecksNeeded,
+ offsets);
int length = actualTypes.length;
actualTypes[length - 2] = inferrer.typeSchemaEnvironment
.getStandardUpperBound(actualKeyType, actualTypes[length - 2],
@@ -2524,7 +2514,8 @@
inferredSpreadTypes,
inferredConditionTypes,
inferenceNeeded,
- typeChecksNeeded);
+ typeChecksNeeded,
+ offsets);
entry.body = body..parent = entry;
inferrer.flowAnalysis.for_updaterBegin();
for (int index = 0; index < entry.updates.length; index++) {
@@ -2576,7 +2567,8 @@
inferredSpreadTypes,
inferredConditionTypes,
inferenceNeeded,
- typeChecksNeeded);
+ typeChecksNeeded,
+ offsets);
entry.body = body..parent = entry;
// This is matched by the call to [forEach_bodyBegin] in
// [handleForInWithoutVariable] or [handleForInDeclaringVariable].
@@ -2603,7 +2595,7 @@
actualTypes.add(valueResult.inferredType);
// Use 'dynamic' for error recovery.
actualTypesForSet.add(const DynamicType());
- mapEntryOffset = entry.fileOffset;
+ offsets.mapEntryOffset = entry.fileOffset;
return entry;
}
}
@@ -2613,18 +2605,19 @@
DartType keyType,
DartType valueType,
Map<TreeNode, DartType> inferredSpreadTypes,
- Map<Expression, DartType> inferredConditionTypes) {
+ Map<Expression, DartType> inferredConditionTypes,
+ _MapLiteralEntryOffsets offsets) {
// It's disambiguated as a map literal.
MapLiteralEntry replacement = entry;
- if (iterableSpreadOffset != null) {
+ if (offsets.iterableSpreadOffset != null) {
replacement = new MapLiteralEntry(
inferrer.helper.buildProblem(
templateSpreadMapEntryTypeMismatch.withArguments(
- iterableSpreadType!, inferrer.isNonNullableByDefault),
- iterableSpreadOffset!,
+ offsets.iterableSpreadType!, inferrer.isNonNullableByDefault),
+ offsets.iterableSpreadOffset!,
1),
new NullLiteral())
- ..fileOffset = iterableSpreadOffset!;
+ ..fileOffset = offsets.iterableSpreadOffset!;
}
if (entry is SpreadMapEntry) {
DartType? spreadType = inferredSpreadTypes[entry.expression];
@@ -2638,11 +2631,11 @@
}
} else if (entry is IfMapEntry) {
MapLiteralEntry then = checkMapEntry(entry.then, keyType, valueType,
- inferredSpreadTypes, inferredConditionTypes);
+ inferredSpreadTypes, inferredConditionTypes, offsets);
entry.then = then..parent = entry;
if (entry.otherwise != null) {
MapLiteralEntry otherwise = checkMapEntry(entry.otherwise!, keyType,
- valueType, inferredSpreadTypes, inferredConditionTypes);
+ valueType, inferredSpreadTypes, inferredConditionTypes, offsets);
entry.otherwise = otherwise..parent = entry;
}
} else if (entry is ForMapEntry) {
@@ -2655,11 +2648,11 @@
entry.condition = condition..parent = entry;
}
MapLiteralEntry body = checkMapEntry(entry.body, keyType, valueType,
- inferredSpreadTypes, inferredConditionTypes);
+ inferredSpreadTypes, inferredConditionTypes, offsets);
entry.body = body..parent = entry;
} else if (entry is ForInMapEntry) {
MapLiteralEntry body = checkMapEntry(entry.body, keyType, valueType,
- inferredSpreadTypes, inferredConditionTypes);
+ inferredSpreadTypes, inferredConditionTypes, offsets);
entry.body = body..parent = entry;
} else {
// Do nothing. Assignability checks are done during type inference.
@@ -2735,11 +2728,8 @@
bool hasMapEntry = false;
bool hasMapSpread = false;
bool hasIterableSpread = false;
+ _MapLiteralEntryOffsets offsets = new _MapLiteralEntryOffsets();
if (inferenceNeeded || typeChecksNeeded) {
- mapEntryOffset = null;
- mapSpreadOffset = null;
- iterableSpreadOffset = null;
- iterableSpreadType = null;
DartType spreadTypeContext = const UnknownType();
if (typeContextIsIterable && !typeContextIsMap) {
spreadTypeContext = inferrer.typeSchemaEnvironment.getTypeAsInstanceOf(
@@ -2754,9 +2744,8 @@
<DartType>[inferredKeyType, inferredValueType]);
}
for (int index = 0; index < node.entries.length; ++index) {
- MapLiteralEntry entry = node.entries[index];
- entry = inferMapEntry(
- entry,
+ MapLiteralEntry entry = inferMapEntry(
+ node.entries[index],
node,
inferredKeyType,
inferredValueType,
@@ -2766,16 +2755,17 @@
inferredSpreadTypes!,
inferredConditionTypes!,
inferenceNeeded,
- typeChecksNeeded);
+ typeChecksNeeded,
+ offsets);
node.entries[index] = entry..parent = node;
if (inferenceNeeded) {
formalTypes!.add(mapType.typeArguments[0]);
formalTypes.add(mapType.typeArguments[1]);
}
}
- hasMapEntry = mapEntryOffset != null;
- hasMapSpread = mapSpreadOffset != null;
- hasIterableSpread = iterableSpreadOffset != null;
+ hasMapEntry = offsets.mapEntryOffset != null;
+ hasMapSpread = offsets.mapSpreadOffset != null;
+ hasIterableSpread = offsets.iterableSpreadOffset != null;
}
if (inferenceNeeded) {
bool canBeSet = !hasMapSpread && !hasMapEntry && !typeContextIsMap;
@@ -2880,8 +2870,13 @@
}
if (typeChecksNeeded) {
for (int index = 0; index < node.entries.length; ++index) {
- MapLiteralEntry entry = checkMapEntry(node.entries[index], node.keyType,
- node.valueType, inferredSpreadTypes!, inferredConditionTypes!);
+ MapLiteralEntry entry = checkMapEntry(
+ node.entries[index],
+ node.keyType,
+ node.valueType,
+ inferredSpreadTypes!,
+ inferredConditionTypes!,
+ offsets);
node.entries[index] = entry..parent = node;
}
}
@@ -7348,3 +7343,18 @@
_UriOffset(this.uri, this.fileOffset);
}
+
+/// Offset and type information collection in [InferenceVisitor.inferMapEntry].
+class _MapLiteralEntryOffsets {
+ // Stores the offset of the map entry found by inferMapEntry.
+ int? mapEntryOffset;
+
+ // Stores the offset of the map spread found by inferMapEntry.
+ int? mapSpreadOffset;
+
+ // Stores the offset of the iterable spread found by inferMapEntry.
+ int? iterableSpreadOffset;
+
+ // Stores the type of the iterable spread found by inferMapEntry.
+ DartType? iterableSpreadType;
+}
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 43b3074..00b7e5e 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
@@ -47,6 +47,7 @@
noLength;
import '../scope.dart';
import '../source/source_class_builder.dart';
+import '../source/source_enum_builder.dart';
import '../source/source_library_builder.dart' show SourceLibraryBuilder;
import '../source/source_loader.dart' show SourceLoader;
import '../source/source_member_builder.dart';
@@ -249,6 +250,15 @@
}
@override
+ VariableDeclaration getFormalParameter(int index) {
+ if (parent is SourceEnumBuilder) {
+ return formals![index + 2].variable!;
+ } else {
+ return super.getFormalParameter(index);
+ }
+ }
+
+ @override
void inferTypes(ClassHierarchyBase hierarchy) {
inferFormalTypes(hierarchy);
}
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.strong.expect b/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.strong.expect
index beb0d94..c6b555c 100644
--- a/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.strong.expect
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.strong.expect
@@ -8,7 +8,7 @@
final field core::int bar;
static const field self::E0 one = #C4;
static const field self::E0 two = #C7;
- const constructor •(core::int #index, core::String #name = #C9, core::int foo, {required core::int bar = #C9}) → self::E0
+ const constructor •(core::int #index, core::String #name, core::int foo, {required core::int bar = #C9}) → self::E0
: self::E0::foo = foo, self::E0::bar = bar, super core::_Enum::•(#index, #name)
;
method toString() → core::String
@@ -19,7 +19,7 @@
final field self::E1::X% foo;
static const field self::E1<core::String> one = #C11;
static const field self::E1<core::int> two = #C12;
- const constructor •(core::int #index = #C9, core::String #name, {required self::E1::X% foo = #C9}) → self::E1<self::E1::X%>
+ const constructor •(core::int #index, core::String #name, {required self::E1::X% foo = #C9}) → self::E1<self::E1::X%>
: self::E1::foo = foo, super core::_Enum::•(#index, #name)
;
method toString() → core::String
@@ -33,7 +33,7 @@
static const field self::E2<core::int, core::String, core::double> one = #C15;
static const field self::E2<core::String, core::int, core::double> two = #C17;
static const field self::E2<core::double, core::bool, dynamic> three = #C21;
- const constructor •(core::int #index, core::String #name = #C9, self::E2::X% foo, {required self::E2::Y% bar = #C9, has-declared-initializer self::E2::Z? baz = #C9}) → self::E2<self::E2::X%, self::E2::Y%, self::E2::Z%>
+ const constructor •(core::int #index, core::String #name, self::E2::X% foo, {required self::E2::Y% bar = #C9, has-declared-initializer self::E2::Z? baz = #C9}) → self::E2<self::E2::X%, self::E2::Y%, self::E2::Z%>
: self::E2::foo = foo, self::E2::bar = bar, self::E2::baz = baz, super core::_Enum::•(#index, #name)
;
method toString() → core::String
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.strong.transformed.expect b/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.strong.transformed.expect
index beb0d94..c6b555c 100644
--- a/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.strong.transformed.expect
@@ -8,7 +8,7 @@
final field core::int bar;
static const field self::E0 one = #C4;
static const field self::E0 two = #C7;
- const constructor •(core::int #index, core::String #name = #C9, core::int foo, {required core::int bar = #C9}) → self::E0
+ const constructor •(core::int #index, core::String #name, core::int foo, {required core::int bar = #C9}) → self::E0
: self::E0::foo = foo, self::E0::bar = bar, super core::_Enum::•(#index, #name)
;
method toString() → core::String
@@ -19,7 +19,7 @@
final field self::E1::X% foo;
static const field self::E1<core::String> one = #C11;
static const field self::E1<core::int> two = #C12;
- const constructor •(core::int #index = #C9, core::String #name, {required self::E1::X% foo = #C9}) → self::E1<self::E1::X%>
+ const constructor •(core::int #index, core::String #name, {required self::E1::X% foo = #C9}) → self::E1<self::E1::X%>
: self::E1::foo = foo, super core::_Enum::•(#index, #name)
;
method toString() → core::String
@@ -33,7 +33,7 @@
static const field self::E2<core::int, core::String, core::double> one = #C15;
static const field self::E2<core::String, core::int, core::double> two = #C17;
static const field self::E2<core::double, core::bool, dynamic> three = #C21;
- const constructor •(core::int #index, core::String #name = #C9, self::E2::X% foo, {required self::E2::Y% bar = #C9, has-declared-initializer self::E2::Z? baz = #C9}) → self::E2<self::E2::X%, self::E2::Y%, self::E2::Z%>
+ const constructor •(core::int #index, core::String #name, self::E2::X% foo, {required self::E2::Y% bar = #C9, has-declared-initializer self::E2::Z? baz = #C9}) → self::E2<self::E2::X%, self::E2::Y%, self::E2::Z%>
: self::E2::foo = foo, self::E2::bar = bar, self::E2::baz = baz, super core::_Enum::•(#index, #name)
;
method toString() → core::String
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.weak.expect b/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.weak.expect
index 67cb833..04b9df2 100644
--- a/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.weak.expect
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.weak.expect
@@ -8,7 +8,7 @@
final field core::int bar;
static const field self::E0 one = #C4;
static const field self::E0 two = #C7;
- const constructor •(core::int #index, core::String #name = #C9, core::int foo, {required core::int bar = #C9}) → self::E0
+ const constructor •(core::int #index, core::String #name, core::int foo, {required core::int bar = #C9}) → self::E0
: self::E0::foo = foo, self::E0::bar = bar, super core::_Enum::•(#index, #name)
;
method toString() → core::String
@@ -19,7 +19,7 @@
final field self::E1::X% foo;
static const field self::E1<core::String> one = #C11;
static const field self::E1<core::int> two = #C12;
- const constructor •(core::int #index = #C9, core::String #name, {required self::E1::X% foo = #C9}) → self::E1<self::E1::X%>
+ const constructor •(core::int #index, core::String #name, {required self::E1::X% foo = #C9}) → self::E1<self::E1::X%>
: self::E1::foo = foo, super core::_Enum::•(#index, #name)
;
method toString() → core::String
@@ -33,7 +33,7 @@
static const field self::E2<core::int, core::String, core::double> one = #C15;
static const field self::E2<core::String, core::int, core::double> two = #C17;
static const field self::E2<core::double, core::bool, dynamic> three = #C21;
- const constructor •(core::int #index, core::String #name = #C9, self::E2::X% foo, {required self::E2::Y% bar = #C9, has-declared-initializer self::E2::Z? baz = #C9}) → self::E2<self::E2::X%, self::E2::Y%, self::E2::Z%>
+ const constructor •(core::int #index, core::String #name, self::E2::X% foo, {required self::E2::Y% bar = #C9, has-declared-initializer self::E2::Z? baz = #C9}) → self::E2<self::E2::X%, self::E2::Y%, self::E2::Z%>
: self::E2::foo = foo, self::E2::bar = bar, self::E2::baz = baz, super core::_Enum::•(#index, #name)
;
method toString() → core::String
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.weak.modular.expect b/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.weak.modular.expect
index 67cb833..04b9df2 100644
--- a/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.weak.modular.expect
@@ -8,7 +8,7 @@
final field core::int bar;
static const field self::E0 one = #C4;
static const field self::E0 two = #C7;
- const constructor •(core::int #index, core::String #name = #C9, core::int foo, {required core::int bar = #C9}) → self::E0
+ const constructor •(core::int #index, core::String #name, core::int foo, {required core::int bar = #C9}) → self::E0
: self::E0::foo = foo, self::E0::bar = bar, super core::_Enum::•(#index, #name)
;
method toString() → core::String
@@ -19,7 +19,7 @@
final field self::E1::X% foo;
static const field self::E1<core::String> one = #C11;
static const field self::E1<core::int> two = #C12;
- const constructor •(core::int #index = #C9, core::String #name, {required self::E1::X% foo = #C9}) → self::E1<self::E1::X%>
+ const constructor •(core::int #index, core::String #name, {required self::E1::X% foo = #C9}) → self::E1<self::E1::X%>
: self::E1::foo = foo, super core::_Enum::•(#index, #name)
;
method toString() → core::String
@@ -33,7 +33,7 @@
static const field self::E2<core::int, core::String, core::double> one = #C15;
static const field self::E2<core::String, core::int, core::double> two = #C17;
static const field self::E2<core::double, core::bool, dynamic> three = #C21;
- const constructor •(core::int #index, core::String #name = #C9, self::E2::X% foo, {required self::E2::Y% bar = #C9, has-declared-initializer self::E2::Z? baz = #C9}) → self::E2<self::E2::X%, self::E2::Y%, self::E2::Z%>
+ const constructor •(core::int #index, core::String #name, self::E2::X% foo, {required self::E2::Y% bar = #C9, has-declared-initializer self::E2::Z? baz = #C9}) → self::E2<self::E2::X%, self::E2::Y%, self::E2::Z%>
: self::E2::foo = foo, self::E2::bar = bar, self::E2::baz = baz, super core::_Enum::•(#index, #name)
;
method toString() → core::String
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.weak.transformed.expect b/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.weak.transformed.expect
index 67cb833..04b9df2 100644
--- a/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.weak.transformed.expect
@@ -8,7 +8,7 @@
final field core::int bar;
static const field self::E0 one = #C4;
static const field self::E0 two = #C7;
- const constructor •(core::int #index, core::String #name = #C9, core::int foo, {required core::int bar = #C9}) → self::E0
+ const constructor •(core::int #index, core::String #name, core::int foo, {required core::int bar = #C9}) → self::E0
: self::E0::foo = foo, self::E0::bar = bar, super core::_Enum::•(#index, #name)
;
method toString() → core::String
@@ -19,7 +19,7 @@
final field self::E1::X% foo;
static const field self::E1<core::String> one = #C11;
static const field self::E1<core::int> two = #C12;
- const constructor •(core::int #index = #C9, core::String #name, {required self::E1::X% foo = #C9}) → self::E1<self::E1::X%>
+ const constructor •(core::int #index, core::String #name, {required self::E1::X% foo = #C9}) → self::E1<self::E1::X%>
: self::E1::foo = foo, super core::_Enum::•(#index, #name)
;
method toString() → core::String
@@ -33,7 +33,7 @@
static const field self::E2<core::int, core::String, core::double> one = #C15;
static const field self::E2<core::String, core::int, core::double> two = #C17;
static const field self::E2<core::double, core::bool, dynamic> three = #C21;
- const constructor •(core::int #index, core::String #name = #C9, self::E2::X% foo, {required self::E2::Y% bar = #C9, has-declared-initializer self::E2::Z? baz = #C9}) → self::E2<self::E2::X%, self::E2::Y%, self::E2::Z%>
+ const constructor •(core::int #index, core::String #name, self::E2::X% foo, {required self::E2::Y% bar = #C9, has-declared-initializer self::E2::Z? baz = #C9}) → self::E2<self::E2::X%, self::E2::Y%, self::E2::Z%>
: self::E2::foo = foo, self::E2::bar = bar, self::E2::baz = baz, super core::_Enum::•(#index, #name)
;
method toString() → core::String
diff --git a/pkg/front_end/testcases/general/issue49216.dart b/pkg/front_end/testcases/general/issue49216.dart
new file mode 100644
index 0000000..1668ed4
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49216.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+enum E {
+ foo;
+
+ const E([int x = 0, String y = "", num? z]);
+ const E.named(int x, {String y = "", bool b = false, String? z, bool? t});
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue49216.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue49216.dart.textual_outline.expect
new file mode 100644
index 0000000..d4f3d20
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49216.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+enum E {
+ foo;
+
+ const E([int x = 0, String y = "", num? z]);
+ const E.named(int x, {String y = "", bool b = false, String? z, bool? t});
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue49216.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue49216.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d4f3d20
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49216.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+enum E {
+ foo;
+
+ const E([int x = 0, String y = "", num? z]);
+ const E.named(int x, {String y = "", bool b = false, String? z, bool? t});
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue49216.dart.weak.expect b/pkg/front_end/testcases/general/issue49216.dart.weak.expect
new file mode 100644
index 0000000..eee9a44
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49216.dart.weak.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class E extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::E> values = #C4;
+ static const field self::E foo = #C3;
+ const constructor •(core::int #index, core::String #name, [core::int x = #C1, core::String y = #C5, core::num? z = #C6]) → self::E
+ : super core::_Enum::•(#index, #name)
+ ;
+ const constructor named(core::int #index, core::String #name, core::int x, {core::String y = #C5, core::bool b = #C7, core::String? z = #C6, core::bool? t = #C6}) → self::E
+ : super core::_Enum::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E.${this.{core::_Enum::_name}{core::String}}";
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = 0
+ #C2 = "foo"
+ #C3 = self::E {index:#C1, _name:#C2}
+ #C4 = <self::E*>[#C3]
+ #C5 = ""
+ #C6 = null
+ #C7 = false
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue49216.dart:
+- E. (from org-dartlang-testcase:///issue49216.dart:8:9)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:103:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/general/issue49216.dart.weak.modular.expect b/pkg/front_end/testcases/general/issue49216.dart.weak.modular.expect
new file mode 100644
index 0000000..eee9a44
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49216.dart.weak.modular.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class E extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::E> values = #C4;
+ static const field self::E foo = #C3;
+ const constructor •(core::int #index, core::String #name, [core::int x = #C1, core::String y = #C5, core::num? z = #C6]) → self::E
+ : super core::_Enum::•(#index, #name)
+ ;
+ const constructor named(core::int #index, core::String #name, core::int x, {core::String y = #C5, core::bool b = #C7, core::String? z = #C6, core::bool? t = #C6}) → self::E
+ : super core::_Enum::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E.${this.{core::_Enum::_name}{core::String}}";
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = 0
+ #C2 = "foo"
+ #C3 = self::E {index:#C1, _name:#C2}
+ #C4 = <self::E*>[#C3]
+ #C5 = ""
+ #C6 = null
+ #C7 = false
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue49216.dart:
+- E. (from org-dartlang-testcase:///issue49216.dart:8:9)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:103:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/general/issue49216.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue49216.dart.weak.outline.expect
new file mode 100644
index 0000000..fa29e74
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49216.dart.weak.outline.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class E extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::E> values = const <self::E>[self::E::foo];
+ static const field self::E foo = const self::E::•(0, "foo");
+ const constructor •(core::int #index, core::String #name, [core::int x = 0, core::String y = "", core::num? z = null]) → self::E
+ : super core::_Enum::•(#index, #name)
+ ;
+ const constructor named(core::int #index, core::String #name, core::int x, {core::String y = "", core::bool b = false, core::String? z = null, core::bool? t = null}) → self::E
+ : super core::_Enum::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E.${this.{core::_Enum::_name}{core::String}}";
+}
+static method main() → dynamic
+ ;
+
+
+Extra constant evaluation status:
+Evaluated: ListLiteral @ org-dartlang-testcase:///issue49216.dart:5:6 -> ListConstant(const <E*>[const E{_Enum.index: 0, _Enum._name: "foo"}])
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue49216.dart:6:3 -> InstanceConstant(const E{_Enum.index: 0, _Enum._name: "foo"})
+Extra constant evaluation: evaluated: 9, effectively constant: 2
diff --git a/pkg/front_end/testcases/general/issue49216.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue49216.dart.weak.transformed.expect
new file mode 100644
index 0000000..eee9a44
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49216.dart.weak.transformed.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class E extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::E> values = #C4;
+ static const field self::E foo = #C3;
+ const constructor •(core::int #index, core::String #name, [core::int x = #C1, core::String y = #C5, core::num? z = #C6]) → self::E
+ : super core::_Enum::•(#index, #name)
+ ;
+ const constructor named(core::int #index, core::String #name, core::int x, {core::String y = #C5, core::bool b = #C7, core::String? z = #C6, core::bool? t = #C6}) → self::E
+ : super core::_Enum::•(#index, #name)
+ ;
+ method toString() → core::String
+ return "E.${this.{core::_Enum::_name}{core::String}}";
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = 0
+ #C2 = "foo"
+ #C3 = self::E {index:#C1, _name:#C2}
+ #C4 = <self::E*>[#C3]
+ #C5 = ""
+ #C6 = null
+ #C7 = false
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue49216.dart:
+- E. (from org-dartlang-testcase:///issue49216.dart:8:9)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:103:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/tools/VERSION b/tools/VERSION
index a2f908b..8c03cac 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 18
PATCH 0
-PRERELEASE 183
+PRERELEASE 184
PRERELEASE_PATCH 0
\ No newline at end of file