[PrimaryConstructors] Update tests for var in enum declaring parameter

language/primary_constructors/header/enum_declaring_parameter_error_test is added exercise this.

language/primary_constructors/syntax/header_syntax_test and language/primary_constructors/syntax/final_formal_parameter_error_test are updated to not use 'var' modifier for enum declaring parameters.

A message is added to the CFE to avoid referring to the implicit const enum primary constructor as "marked as 'const'".

Part of #61524 #61700

Change-Id: Ic2c3c43d08c42d44dade04c116a73e3be1d22bd5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/478420
Reviewed-by: Erik Ernst <eernst@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Johnni Winther
2026-02-06 03:44:45 -08:00
committed by Commit Queue
parent 3c86e1eb1e
commit 4ca0fde9f7
12 changed files with 53 additions and 19 deletions
@@ -3604,6 +3604,13 @@ const MessageCode enumAbstractMember = const MessageCode(
problemMessage: """Enums can't declare abstract members.""",
);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const MessageCode enumConstructorNonFinalField = const MessageCode(
"EnumConstructorNonFinalField",
problemMessage:
"""Enum constructors are constant so all fields must be final.""",
);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const MessageCode enumConstructorSuperInitializer = const MessageCode(
"EnumConstructorSuperInitializer",
@@ -1558,7 +1558,9 @@ class KernelTarget {
if (constructor.isEffectivelyRedirecting) continue;
if (constructor.isConst && nonFinalFields.isNotEmpty) {
classDeclaration.libraryBuilder.addProblem(
diag.constConstructorNonFinalField,
classDeclaration.isEnum
? diag.enumConstructorNonFinalField
: diag.constConstructorNonFinalField,
constructor.fileOffset,
noLength,
constructor.fileUri,
+10
View File
@@ -3704,6 +3704,16 @@ constConstructorNonFinalField:
const Foo(this.i);
}
enumConstructorNonFinalField:
parameters: none
problemMessage: "Enum constructors are constant so all fields must be final."
experiments: primary-constructors
script:
- |
enum E(var int x) { a(0) }
- |
enum E() { a; int x = 0; }
constConstructorNonFinalFieldCause:
parameters: none
problemMessage: "Field isn't final, but constructor is 'const'."
@@ -7,7 +7,7 @@ library;
// final int? b; // Error
// ^
//
// pkg/front_end/testcases/primary_constructors/enum_primary_constructor.dart:18:14: Error: Constructor is marked 'const' so all fields must be final.
// pkg/front_end/testcases/primary_constructors/enum_primary_constructor.dart:18:14: Error: Enum constructors are constant so all fields must be final.
// enum const E4() { // Error
// ^
// pkg/front_end/testcases/primary_constructors/enum_primary_constructor.dart:20:8: Context: Field isn't final, but constructor is 'const'.
@@ -7,7 +7,7 @@ library;
// final int? b; // Error
// ^
//
// pkg/front_end/testcases/primary_constructors/enum_primary_constructor.dart:18:14: Error: Constructor is marked 'const' so all fields must be final.
// pkg/front_end/testcases/primary_constructors/enum_primary_constructor.dart:18:14: Error: Enum constructors are constant so all fields must be final.
// enum const E4() { // Error
// ^
// pkg/front_end/testcases/primary_constructors/enum_primary_constructor.dart:20:8: Context: Field isn't final, but constructor is 'const'.
@@ -7,7 +7,7 @@ library;
// final int? b; // Error
// ^
//
// pkg/front_end/testcases/primary_constructors/enum_primary_constructor.dart:18:14: Error: Constructor is marked 'const' so all fields must be final.
// pkg/front_end/testcases/primary_constructors/enum_primary_constructor.dart:18:14: Error: Enum constructors are constant so all fields must be final.
// enum const E4() { // Error
// ^
// pkg/front_end/testcases/primary_constructors/enum_primary_constructor.dart:20:8: Context: Field isn't final, but constructor is 'const'.
@@ -10,7 +10,7 @@ library;
// enum const E7({int? a, required int b, int c = 42]) {
// ^
//
// pkg/front_end/testcases/primary_constructors/enum_primary_declaring_parameters.dart:7:14: Error: Constructor is marked 'const' so all fields must be final.
// pkg/front_end/testcases/primary_constructors/enum_primary_declaring_parameters.dart:7:14: Error: Enum constructors are constant so all fields must be final.
// enum const E2(var int i) { x(0) } // Error
// ^
// pkg/front_end/testcases/primary_constructors/enum_primary_declaring_parameters.dart:7:23: Context: Field isn't final, but constructor is 'const'.
@@ -10,7 +10,7 @@ library;
// enum const E7({int? a, required int b, int c = 42]) {
// ^
//
// pkg/front_end/testcases/primary_constructors/enum_primary_declaring_parameters.dart:7:14: Error: Constructor is marked 'const' so all fields must be final.
// pkg/front_end/testcases/primary_constructors/enum_primary_declaring_parameters.dart:7:14: Error: Enum constructors are constant so all fields must be final.
// enum const E2(var int i) { x(0) } // Error
// ^
// pkg/front_end/testcases/primary_constructors/enum_primary_declaring_parameters.dart:7:23: Context: Field isn't final, but constructor is 'const'.
@@ -10,7 +10,7 @@ library;
// enum const E7({int? a, required int b, int c = 42]) {
// ^
//
// pkg/front_end/testcases/primary_constructors/enum_primary_declaring_parameters.dart:7:14: Error: Constructor is marked 'const' so all fields must be final.
// pkg/front_end/testcases/primary_constructors/enum_primary_declaring_parameters.dart:7:14: Error: Enum constructors are constant so all fields must be final.
// enum const E2(var int i) { x(0) } // Error
// ^
// pkg/front_end/testcases/primary_constructors/enum_primary_declaring_parameters.dart:7:23: Context: Field isn't final, but constructor is 'const'.
@@ -0,0 +1,24 @@
// Copyright (c) 2026, 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.
// An enum cannot declare mutable fields through declaring parameters.
// SharedOptions=--enable-experiment=primary-constructors
enum E1(var int x) {
// ^
// [analyzer] unspecified
// [cfe] Enum constructors are constant so all fields must be final.
a(0)
}
enum E2() {
// ^
// [analyzer] unspecified
// [cfe] Enum constructors are constant so all fields must be final.
a;
int x = 0;
}
@@ -19,10 +19,7 @@ class C {
// [cfe] unspecified
}
enum E(var int x) {
// ^
// [analyzer] unspecified
// [cfe] unspecified
enum E(final int x) {
e(1);
void method1(final int x) {}
// ^
@@ -33,20 +33,14 @@ class CSuperParameters(final int x, super.y) extends C1;
// Named parameters (regular and required).
class CNamedParameters({final int x = 1, required var int y});
enum EnumNamedParameters({final int x = 1, required var int y}) {
// ^
// [analyzer] unspecified
// [cfe] unspecified
enum EnumNamedParameters({final int x = 1, required final int y}) {
e(x: 2, y: 3), f(y: 3);
}
// Optional parameters.
class COptionalParameters([final int x = 1, var int y = 2]);
enum EnumOptionalParameters([final int x = 1, var int y = 2]) {
// ^
// [analyzer] unspecified
// [cfe] unspecified
enum EnumOptionalParameters([final int x = 1, final int y = 2]) {
e(3, 4), f(3), g();
}