@@ -4,7 +4,7 @@ Author: Erik Ernst
44
55Status: Accepted
66
7- Version: 1.12
7+ Version: 1.13
88
99Experiment flag: declaring-constructors
1010
@@ -191,10 +191,12 @@ that the instance variable declaration which is induced by this declaring
191191constructor parameter is ` final ` .
192192
193193In the case where the declaration is an ` extension type ` , the modifier
194- ` final ` on the representation variable can be specified or omitted. Note
195- that an extension type declaration is specified to use a primary
196- constructor (it is not supported to declare the representation variable
197- using a normal instance variable declaration):
194+ ` final ` on the representation variable can be specified or omitted. It is
195+ an error to specify the modifier ` var ` on the representation variable.
196+
197+ An extension type declaration must have a primary constructor and its
198+ single parameter is always declaring. The representation variable cannot be
199+ declared using a normal instance variable declaration:
198200
199201``` dart
200202// Using a primary constructor.
@@ -220,7 +222,7 @@ We can omit the type of an optional parameter with a default value,
220222in which case the type is inferred from the default value:
221223
222224``` dart
223- // Infer the declared type from default value.
225+ // Infers the declared type from the default value.
224226class Point(var int x, [var y = 0]);
225227```
226228
@@ -695,10 +697,10 @@ latter is the current scope for the initializing expressions of all
695697non-late instance variable declarations, in addition to the initializer
696698list of the body part of the constructor.*
697699
698- * The point is that the body part of the primary constructor should have
699- access to the "regular" parameters, but it should have access to the
700- instance variables rather than the declaring or initializing parameters
701- with the same names. For example:*
700+ * The point is that the function body of the body part of the primary
701+ constructor should have access to the "regular" parameters, but it should
702+ have access to the instance variables rather than the declaring or
703+ initializing parameters with the same names. For example:*
702704
703705``` dart
704706class C(var String x) {
@@ -745,16 +747,33 @@ main() {
745747}
746748```
747749
750+ A compile-time error occurs if an assignment to a primary parameter occurs
751+ in the initializing expression of a non-late instance variable, or in the
752+ initializer list of the body part of a primary constructor.
753+
754+ * This includes expressions like ` p++ ` where the assignment is implicit.
755+ The rule does not apply to late instance variables or (late or non-late)
756+ static variables. The primary constructor parameters are not in scope for
757+ initializer expressions of those variables.*
758+
759+ Consider a class with a primary constructor that also has a body part with
760+ an initializer list. A compile-time error occurs if an instance variable
761+ declaration has an initializing expression, and it is also initialized by
762+ an element in the initializer list of the body part, or by an initializing
763+ formal parameter of the primary constructor.
764+
765+ * This is already an error when the instance variable is final, but no such
766+ error is raised when the instance variable is mutable and the initializer
767+ list is part of a non-primary constructor. However, with a primary
768+ constructor this situation will always cause the value of the initializing
769+ expression in the variable declaration to be overwritten by the value in
770+ the initializer list, which makes the situation more confusing than
771+ useful.*
772+
748773The following errors apply to formal parameters of a primary constructor.
749774Let _ p_ be a formal parameter of a primary constructor in a class, mixin
750775class, enum, or extension type declaration _ D_ named ` C ` :
751776
752- A compile-time error occurs if _ p_ contains a term of the form ` this.v ` , or
753- ` super.v ` where ` v ` is an identifier, and _ p_ has the modifier
754- ` covariant ` . * For example, ` required covariant int this.v ` is an error. The
755- reason for this error is that the modifier ` covariant ` must be specified on
756- the declaration of ` v ` which is known to exist, not on the parameter.*
757-
758777A compile-time error occurs if _ p_ has the modifier ` covariant ` , but
759778not ` var ` . * This parameter does not induce a setter.*
760779
@@ -782,13 +801,13 @@ Let `p` be a formal parameter in _k_ which has the modifier `var` or the
782801modifier ` final ` * (that is, ` p ` is a declaring parameter)* .
783802
784803Consider the situation where ` p ` has no type annotation:
785- - if combined member signature for a getter with the same name as ` p ` from
786- the superinterfaces of _ D_ exists and has return type ` T ` , the parameter
787- ` p ` has declared type ` T ` . If no such getter exists, but a setter with
788- the same basename exists, with a formal parameter whose type is ` T ` , the
789- parameter ` p ` has declared type ` T ` . * In other words, an instance
790- variable introduced by a declaring parameter is subject to override
791- inference, just like an explicitly declared instance variable.*
804+ - if the combined member signature for a getter with the same name as ` p `
805+ from the superinterfaces of _ D_ exists and has return type ` T ` , the
806+ parameter ` p ` has declared type ` T ` . If no such getter exists, but a
807+ setter with the same basename exists, with a formal parameter whose type
808+ is ` T ` , the parameter ` p ` has declared type ` T ` . * In other words, an
809+ instance variable introduced by a declaring parameter is subject to
810+ override inference, just like an explicitly declared instance variable.*
792811- otherwise, if ` p ` is optional and has a default value whose static type
793812 in the empty context is a type ` T ` which is not ` Null ` then ` p ` has
794813 declared type ` T ` . When ` T ` is ` Null ` , ` p ` instead has declared type
@@ -810,8 +829,10 @@ specifying the current scope explicitly as the body scope, in spite of the
810829fact that the primary constructor is actually placed outside the braces
811830that delimit the class body.*
812831
813- Next, _ k2_ has the modifier ` const ` iff the keyword ` const ` occurs just
814- before the name of _ D_ , or _ D_ is an ` enum ` declaration.
832+ Next, _ k2_ has the modifier ` const ` if and only if the keyword ` const `
833+ occurs just before the name of _ D_ or _ D_ is an ` enum ` declaration. In any
834+ case, such an occurrence of ` const ` in the header of _ D_ is omitted in
835+ _ D2_ .
815836
816837Consider the case where _ k_ is a primary constructor. If the name ` C ` in
817838_ D_ and the type parameter list, if any, is followed by ` .id ` where ` id ` is
@@ -832,26 +853,32 @@ positional or named parameter remains optional; if it has a default value
832853` d ` in _ L_ then it has the default value ` d ` in _ L2_ as well.
833854
834855- An initializing formal parameter * (e.g., ` T this.x ` )* is copied from _ L_
835- to _ L2_ , along with the default value, if any, and is otherwise unchanged.
836- - A super parameter is copied from _ L_ to _ L2_ along with the default
837- value, if any, and is otherwise unchanged.
856+ to _ L2_ , with no changes.
857+ - A super parameter is copied from _ L_ to _ L2_ any, with no changes.
838858- A formal parameter which is not covered by the previous two cases and
839859 which does not have the modifier ` var ` or the modifier ` final ` is copied
840860 unchanged from _ L_ to _ L2_ * (this is a plain, non-declaring parameter)* .
841- - Otherwise, a formal parameter (named or positional) of the form ` var T p `
842- or ` final T p ` where ` T ` is a type and ` p ` is an identifier is replaced
843- in _ L2_ by ` this.p ` , along with its default value, if any. Next, a
861+ - Otherwise, it is a declaring parameter. A formal parameter (named or
862+ positional) of the form ` var T p ` or ` final T p ` where ` T ` is a type and
863+ ` p ` is an identifier is replaced in _ L2_ by ` this.p ` , along with its
864+ default value, if any. The same is done in the case where the formal
865+ parameter has the form ` var p ` or ` final p ` , and ` T ` is the declared type
866+ of ` p ` which was obtained by inference. If the parameter has the modifier
867+ ` var ` and _ D_ is an extension type declaration then a compile-time error
868+ occurs. Otherwise, if _ D_ is not an extension type declaration, a
844869 semantic instance variable declaration corresponding to the syntax ` T p; `
845- or ` final T p; ` is added to _ D2_ . It includes the modifier ` final ` if the
846- parameter in _ L_ has the modifier ` final ` and _ D_ is not an `extension
847- type` decaration; if _D_ is an ` extension type` declaration then the name
848- of ` p ` specifies the name of the representation variable. In all cases, if
849- ` p ` has the modifier ` covariant ` then this modifier is removed from the
850- parameter in _ L2_ , and it is added to the instance variable declaration
851- named ` p ` .
852-
853- If there is an initializer list following the formal parameter list _ L_
854- then _ k2_ has an initializer list with the same elements in the same order.
870+ or ` final T p; ` is added to _ D2_ . It includes the modifier ` final ` if and
871+ only if the parameter in _ L_ has the modifier ` final ` and _ D_ is not an
872+ ` extension type ` decaration. Otherwise, if _ D_ is an ` extension type `
873+ declaration then the name of ` p ` specifies the name of the representation
874+ variable. In all cases, if ` p ` has the modifier ` covariant ` then this
875+ modifier is removed from the parameter in _ L2_ , and it is added to the
876+ instance variable declaration named ` p ` .
877+
878+ If there is a primary constructor body part that contains an initializer
879+ list then _ k2_ has an initializer list with the same elements in the same
880+ order. If that body part has a function body then _ k2_ has the same
881+ function body.
855882
856883Finally, _ k2_ is added to _ D2_ , and _ D_ is replaced by _ D2_ .
857884
@@ -899,6 +926,13 @@ of declaration, and the constructor might be non-const).
899926
900927### Changelog
901928
929+ 1.13 - November 25, 2025
930+
931+ * Specify that an assignment to a primary parameter in initialization code
932+ is an error. Specify an error for double initialization of a mutable
933+ instance variable in the declaration and in a primary constructor
934+ initializer list.
935+
9029361.12 - November 6, 2025
903937
904938* Eliminate in-body declaring constructors. Revert to the terminology where
0 commit comments