From 4ca0fde9f739f54d4535d9a7b8e8e4b9a1106bce Mon Sep 17 00:00:00 2001 From: Johnni Winther Date: Fri, 6 Feb 2026 03:44:45 -0800 Subject: [PATCH] [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 Commit-Queue: Johnni Winther --- pkg/front_end/lib/src/codes/diagnostic.g.dart | 7 ++++++ .../lib/src/kernel/kernel_target.dart | 4 +++- pkg/front_end/messages.yaml | 10 ++++++++ ...num_primary_constructor.dart.strong.expect | 2 +- ...ary_constructor.dart.strong.modular.expect | 2 +- ...constructor.dart.strong.transformed.expect | 2 +- ...ry_declaring_parameters.dart.strong.expect | 2 +- ...ring_parameters.dart.strong.modular.expect | 2 +- ..._parameters.dart.strong.transformed.expect | 2 +- .../enum_declaring_parameter_error_test.dart | 24 +++++++++++++++++++ .../final_formal_parameter_error_test.dart | 5 +--- .../syntax/header_syntax_test.dart | 10 ++------ 12 files changed, 53 insertions(+), 19 deletions(-) create mode 100644 tests/language/primary_constructors/header/enum_declaring_parameter_error_test.dart diff --git a/pkg/front_end/lib/src/codes/diagnostic.g.dart b/pkg/front_end/lib/src/codes/diagnostic.g.dart index dac1657a6f6..7dc93a647b1 100644 --- a/pkg/front_end/lib/src/codes/diagnostic.g.dart +++ b/pkg/front_end/lib/src/codes/diagnostic.g.dart @@ -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", diff --git a/pkg/front_end/lib/src/kernel/kernel_target.dart b/pkg/front_end/lib/src/kernel/kernel_target.dart index 2ee3adf5dbd..07f0b840ede 100644 --- a/pkg/front_end/lib/src/kernel/kernel_target.dart +++ b/pkg/front_end/lib/src/kernel/kernel_target.dart @@ -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, diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml index b8f7bea7894..f5296a4520e 100644 --- a/pkg/front_end/messages.yaml +++ b/pkg/front_end/messages.yaml @@ -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'." diff --git a/pkg/front_end/testcases/primary_constructors/enum_primary_constructor.dart.strong.expect b/pkg/front_end/testcases/primary_constructors/enum_primary_constructor.dart.strong.expect index ef799e36da5..637b043be0f 100644 --- a/pkg/front_end/testcases/primary_constructors/enum_primary_constructor.dart.strong.expect +++ b/pkg/front_end/testcases/primary_constructors/enum_primary_constructor.dart.strong.expect @@ -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'. diff --git a/pkg/front_end/testcases/primary_constructors/enum_primary_constructor.dart.strong.modular.expect b/pkg/front_end/testcases/primary_constructors/enum_primary_constructor.dart.strong.modular.expect index ef799e36da5..637b043be0f 100644 --- a/pkg/front_end/testcases/primary_constructors/enum_primary_constructor.dart.strong.modular.expect +++ b/pkg/front_end/testcases/primary_constructors/enum_primary_constructor.dart.strong.modular.expect @@ -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'. diff --git a/pkg/front_end/testcases/primary_constructors/enum_primary_constructor.dart.strong.transformed.expect b/pkg/front_end/testcases/primary_constructors/enum_primary_constructor.dart.strong.transformed.expect index ef799e36da5..637b043be0f 100644 --- a/pkg/front_end/testcases/primary_constructors/enum_primary_constructor.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/primary_constructors/enum_primary_constructor.dart.strong.transformed.expect @@ -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'. diff --git a/pkg/front_end/testcases/primary_constructors/enum_primary_declaring_parameters.dart.strong.expect b/pkg/front_end/testcases/primary_constructors/enum_primary_declaring_parameters.dart.strong.expect index cf135702378..9b3a3029955 100644 --- a/pkg/front_end/testcases/primary_constructors/enum_primary_declaring_parameters.dart.strong.expect +++ b/pkg/front_end/testcases/primary_constructors/enum_primary_declaring_parameters.dart.strong.expect @@ -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'. diff --git a/pkg/front_end/testcases/primary_constructors/enum_primary_declaring_parameters.dart.strong.modular.expect b/pkg/front_end/testcases/primary_constructors/enum_primary_declaring_parameters.dart.strong.modular.expect index cf135702378..9b3a3029955 100644 --- a/pkg/front_end/testcases/primary_constructors/enum_primary_declaring_parameters.dart.strong.modular.expect +++ b/pkg/front_end/testcases/primary_constructors/enum_primary_declaring_parameters.dart.strong.modular.expect @@ -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'. diff --git a/pkg/front_end/testcases/primary_constructors/enum_primary_declaring_parameters.dart.strong.transformed.expect b/pkg/front_end/testcases/primary_constructors/enum_primary_declaring_parameters.dart.strong.transformed.expect index cf135702378..9b3a3029955 100644 --- a/pkg/front_end/testcases/primary_constructors/enum_primary_declaring_parameters.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/primary_constructors/enum_primary_declaring_parameters.dart.strong.transformed.expect @@ -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'. diff --git a/tests/language/primary_constructors/header/enum_declaring_parameter_error_test.dart b/tests/language/primary_constructors/header/enum_declaring_parameter_error_test.dart new file mode 100644 index 00000000000..9a0011cb687 --- /dev/null +++ b/tests/language/primary_constructors/header/enum_declaring_parameter_error_test.dart @@ -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; +} \ No newline at end of file diff --git a/tests/language/primary_constructors/syntax/final_formal_parameter_error_test.dart b/tests/language/primary_constructors/syntax/final_formal_parameter_error_test.dart index cb95746f36f..4c8219c4ee0 100644 --- a/tests/language/primary_constructors/syntax/final_formal_parameter_error_test.dart +++ b/tests/language/primary_constructors/syntax/final_formal_parameter_error_test.dart @@ -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) {} // ^ diff --git a/tests/language/primary_constructors/syntax/header_syntax_test.dart b/tests/language/primary_constructors/syntax/header_syntax_test.dart index 688f32a4269..e0d348b6980 100644 --- a/tests/language/primary_constructors/syntax/header_syntax_test.dart +++ b/tests/language/primary_constructors/syntax/header_syntax_test.dart @@ -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(); }