[tests] Declaring constructors - Tests for covariant modifier.
Tests the following:
- A compile-time error occurs if the formal parameter contains a term of
the form `this.v`, or `super.v` where `v` is an identifier, and the
parameter has the modifier `covariant`.
- We allow formal parameters of a declaring constructor to have the
`covariant` modifier with `var`.
- It is an error for a formal parameter of a declaring constructor to be
both `covariant` and `final`.
- It is an error for a formal parameter of a declaring constructor to
have the `covariant` modifier but not the `var` modifier.
Bug: https://github.com/dart-lang/sdk/issues/61687
Change-Id: I6c2a258a3a5d02c9ec33ef944c3655917a4899fb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/454980
Commit-Queue: Kallen Tu <kallentu@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
diff --git a/tests/language/declaring_constructors/syntax/covariant_super_this_error_test.dart b/tests/language/declaring_constructors/syntax/covariant_super_this_error_test.dart
new file mode 100644
index 0000000..73ec92f
--- /dev/null
+++ b/tests/language/declaring_constructors/syntax/covariant_super_this_error_test.dart
@@ -0,0 +1,128 @@
+// Copyright (c) 2025, 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.
+
+// A compile-time error occurs if the formal parameter contains a term of the
+// form `this.v`, or `super.v` where `v` is an identifier, and the parameter has
+// the modifier `covariant`.
+
+// SharedOptions=--enable-experiment=declaring-constructors
+
+// `covariant` with `this.x`
+
+// In-header declaring constructor
+class C1(covariant this.x) {
+ // ^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+ int x;
+}
+
+
+class C2({covariant this.x}) {
+ // ^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+ int? x;
+}
+
+class C3({required covariant this.x}) {
+ // ^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+ int x;
+}
+
+class C4([covariant this.x]) {
+ // ^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+ int? x;
+}
+
+// In-body declaring constructor
+class C5 {
+ int? x;
+ this(covariant this.x);
+ // ^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+}
+
+class C6 {
+ int x;
+ this({covariant this.x});
+ // ^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+}
+
+class C7 {
+ int x;
+ this({required covariant this.x});
+ // ^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+}
+
+class C8 {
+ int? x;
+ this([covariant this.x]);
+ // ^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+}
+
+// `covariant` with `super.x`
+
+class A(final int? x);
+
+// In-header declaring constructor
+class C9(covariant super.x) extends A;
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+class C10({covariant super.x}) extends A;
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+class C11({required covariant super.x}) extends A;
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+class C12([covariant super.x]) extends A;
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+// In-body declaring constructor
+class C13 extends A {
+ this(covariant super.x);
+ // ^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+}
+
+class C14 extends A {
+ this({covariant super.x});
+ // ^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+}
+
+class C15 extends A {
+ this({required covariant super.x});
+ // ^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+}
+
+class C16 extends A {
+ this([covariant super.x]);
+ // ^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+}
diff --git a/tests/language/declaring_constructors/syntax/covariant_var_test.dart b/tests/language/declaring_constructors/syntax/covariant_var_test.dart
new file mode 100644
index 0000000..7365064
--- /dev/null
+++ b/tests/language/declaring_constructors/syntax/covariant_var_test.dart
@@ -0,0 +1,83 @@
+// Copyright (c) 2025, 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.
+
+// Allow the modifier `covariant` in declaring parameters.
+
+// SharedOptions=--enable-experiment=declaring-constructors
+
+import 'package:expect/expect.dart';
+
+class A {}
+class B extends A {}
+
+class C1(covariant var A x);
+class D1(var B x) implements C1;
+
+class C2({covariant var A? x});
+class D2({var B? x}) implements C2;
+
+class C3({required covariant var A x});
+class D3({required var B x}) implements C2;
+
+class C4([covariant var A? x]);
+class D4([var B? x]) implements C2;
+
+class C5 {
+ this(covariant var A x);
+}
+class D5 implements C5 {
+ this(var B x);
+}
+
+class C6 {
+ this({covariant var A? x});
+}
+class D6 {
+ this({var B? x});
+}
+
+class C7 {
+ this({required covariant var A x});
+}
+class D7 {
+ this({required var B x});
+}
+
+class C8 {
+ this([covariant var A? x]);
+}
+class D8 {
+ this([var B? x]);
+}
+
+void main() {
+ A a = A();
+ B b = B();
+
+ // In-header
+ Expect.equals(a, C1(a).x);
+ Expect.equals(b, D1(b).x);
+
+ Expect.equals(a, C2(x: a).x);
+ Expect.equals(b, D2(x: b).x);
+
+ Expect.equals(a, C3(x: a).x);
+ Expect.equals(b, D3(x: b).x);
+
+ Expect.equals(a, C4(a).x);
+ Expect.equals(b, D4(b).x);
+
+ // In-body
+ Expect.equals(a, C5(a).x);
+ Expect.equals(b, D5(b).x);
+
+ Expect.equals(a, C6(x: a).x);
+ Expect.equals(b, D6(x: b).x);
+
+ Expect.equals(a, C7(x: a).x);
+ Expect.equals(b, D7(x: b).x);
+
+ Expect.equals(a, C8(a).x);
+ Expect.equals(b, D8(b).x);
+}
diff --git a/tests/language/declaring_constructors/syntax/covariant_with_final_error_test.dart b/tests/language/declaring_constructors/syntax/covariant_with_final_error_test.dart
new file mode 100644
index 0000000..268162e
--- /dev/null
+++ b/tests/language/declaring_constructors/syntax/covariant_with_final_error_test.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2025, 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.
+
+// It is an error for a formal parameter to be both `covariant` and `final`.
+
+// SharedOptions=--enable-experiment=declaring-constructors
+
+class C1(covariant final int x);
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+class C2({covariant final int? x = 1});
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+class C3({required covariant final int x});
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+class C4([covariant final int? x]);
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+class C5 {
+ this(covariant final int x);
+ // ^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+}
+
+class C6 {
+ this({covariant final int? x});
+ // ^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+}
+
+class C7 {
+ this({required covariant final int x});
+ // ^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+}
+
+class C8 {
+ this([covariant final int? x]);
+ // ^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+}
+
+extension type E1(covariant final int x);
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+extension type E2(covariant int x);
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
diff --git a/tests/language/declaring_constructors/syntax/covariant_without_var_error_test.dart b/tests/language/declaring_constructors/syntax/covariant_without_var_error_test.dart
new file mode 100644
index 0000000..b141b5c
--- /dev/null
+++ b/tests/language/declaring_constructors/syntax/covariant_without_var_error_test.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2025, 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.
+
+// It is an error for a formal parameter to have the `covariant` modifier
+// but not the `var` modifier.
+
+// SharedOptions=--enable-experiment=declaring-constructors
+
+class C1(covariant int x);
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+class C2({covariant int? x});
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+class C3({required covariant int x});
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+class C4([covariant int? x]);
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+
+class C5 {
+ this(covariant int x);
+ // ^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+}
+
+class C6 {
+ this({covariant int? x});
+ // ^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+}
+
+class C7 {
+ this({required covariant int x});
+ // ^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+}
+
+class C8 {
+ this([covariant int? x]);
+ // ^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+}