@@ -567,7 +567,7 @@ have one or more other capabilities:
567567 additional updates and/or checks.)
568568
569569Variable declarations may be marked ` abstract ` or ` external ` and, if so,
570- those are mapped over to the corresponding getter and setter functions.
570+ those are mapped over to the corresponding getter and setter functions.
571571
572572An ` abstract ` variable declaration is equivalent to an abstract getter
573573declaration, and if not ` final ` , also an abstract setter declaration. An
@@ -784,39 +784,38 @@ It is a compile-time error if:
784784
785785### Augmenting constructors
786786
787- Constructors are (as always) more complex. A constructor marked ` augment `
788- replaces the body of the existing constructor with its body, if present. If the
789- augmenting constructor has any initializers, they are appended to the augmented
790- constructor's initializers, but before any super initializer or redirecting
791- initializer if there is one.
792-
793- In the augmenting constructor's body, an ` augmented() ` call invokes the
794- augmented constructor's body. The expression has type ` void ` and evaluates to
795- ` null ` . ** (TODO: This is slightly under-specified. We can use the current
796- bindings of the parameters of the augmenting constructor as the initial binding
797- of parameter variables in the augmented body, or we can execute the body in the
798- current * scope* , using the same variables as the current body. The latter is
799- not what we do with functions elsewhere, and allows the ` augmented ` expression
800- to modify local variables, but the former introduces different variables than
801- the ones that existed when evaluating the initializer list. If the initializer
802- list captures variables in closures, that body may not work.)**
787+ Constructors are (as always) more complex. We have many kinds of constructors,
788+ and what it means to augment each is different. For the purposes of this section
789+ we will call out three specific kinds of constructors:
790+
791+ ** Non-redirecting generative constructors** : These always produce a new
792+ instance, and have an optional initializer list and optional body.
793+ ** Non-redirecting factory constructors** : These are much like static methods,
794+ and might return a subtype of the current type. They also may not create a new
795+ instance, but return an existing one. They must have a body.
796+ ** Redirecting constructors** : Both generative and factory constructors can be
797+ redirecting, although the syntax looks slightly different for each.
798+
799+ It may not always be apparent whether a constructor is redirecting or not based
800+ on a given declaration (if there is no body, initializer list, or redirecting
801+ constructor invocation). These constructors are considered to be "potentially
802+ redirecting" or "potentially non-redirecting". An augmentation may alter this
803+ property by augmenting a constructor in a way that makes it concretely
804+ redirecting or not.
803805
804806It is a compile-time error if:
805807
806- * The function signature of the augmenting constructor does not match the
807- signature of the augmented constructor. This means that the parameters must
808- be the same (just as for augmenting functions, except here there is no
809- return type and no type parameters on the constructor itself). Any
810- initializing formals must be the same in both constructors. Any super
811- parameters must be the same in both constructors.
812-
813- ** TODO: Is this the right way to handle initializing formals?**
808+ * The signature of the constructor augmentation does not match the original
809+ constructor. It must have the same number of positional parameters, the same
810+ named parameters, and matching parameters must have the same type,
811+ optionality, and any ` required ` modifiers must match. Any initializing
812+ formals and super parameters must also be the same in both constructors.
814813
815814* The augmenting constructor parameters specify any default values.
816815 * Default values are defined solely by the introductory constructor.*
817816
818817* The introductory constructor is ` const ` and the augmenting constructor
819- is not, or vice versa.
818+ is not or vice versa.
820819
821820* The introductory constructor is marked ` factory ` and the augmenting
822821 constructor is not, or vice versa.
@@ -828,7 +827,99 @@ It is a compile-time error if:
828827 replace a declared super constructor._ ** (TODO: Why not? We allow
829828 "replacing implementation", and this is * something* like that.)**
830829
831- ** TODO: What about redirecting constructors?**
830+ * The resulting constructor is not valid (has a redirecting initializer and
831+ other initializers, multiple ` super ` initializers, etc).
832+
833+ * A non-redirecting constructor augments a constructor which is not
834+ potentially non-redirecting.
835+
836+ * A redirecting constructor augments a constructor which is not potentially
837+ redirecting.
838+
839+ #### Non-redirecting generative constructors
840+
841+ These are probably the most complex constructor, but also the most common.
842+
843+ A non-redirecting generative constructor marked ` augment ` may:
844+
845+ * Add or replace the body of the augmented constructor with a new body.
846+
847+ * If the augmenting constructor has an explicit block body, then that body
848+ replaces any existing constructor body.
849+
850+ * In the augmenting constructor's body, an ` augmented() ` call executes the
851+ augmented constructor's body in the same parameter scope that the
852+ augmenting body is executing in. The expression has type ` void ` and
853+ evaluates to ` null ` . ** (TODO: This is slightly under-specified. We can
854+ use the current bindings of the parameters of the augmenting constructor
855+ as the initial binding of parameter variables in the augmented body, or
856+ we can execute the body in the current * scope* , using the same variables
857+ as the current body. The latter is not what we do with functions
858+ elsewhere, and allows the ` augmented() ` expression to modify local
859+ variables, but the former introduces different variables than the ones
860+ that existed when evaluating the initializer list. If the initializer
861+ list captures variables in closures, that body may not work.)**
862+
863+ * Initializer lists _ are not_ re-run, they have already executed and
864+ shouldn't be executed twice. The same goes for initializing formals and
865+ super parameters.
866+
867+ * If a parameter variable is overwritten prior to calling ` augmented() ` ,
868+ the augmented body will see the updated value, because the parameter
869+ scope is identical.
870+
871+ * Local variables in scope where augmented is evaluated are not in scope
872+ for the execution of the augmented constructor's body.
873+
874+ * Add initializers to the initializer list. If the augmenting constructor has
875+ an initializer list then:
876+
877+ * It's a compile-time error if the augmented constructor has
878+ super-initializer, and the augmenting constructor's initializer list
879+ also contains a super-initializer.
880+
881+ * Otherwise the result of applying the augmenting constructor has an
882+ initializer list containing first the assertions and field initializers
883+ of the augmented constructor, if any, then the assertions and field
884+ initializers of the augmenting constructor, and finally any
885+ super-initializer of either the augmeted or augmenting constructor.
886+
887+ #### Non-redirecting factory constructors
888+
889+ A non-redirecting factory constructor marked ` augment ` works in the same way as
890+ a normal function augmentation.
891+
892+ If it has a body, it replaces the body of the augmented constructor (if
893+ present), and it may invoke the augmented body by calling
894+ ` augmented(arguments) ` .
895+
896+ #### Redirecting generative constructors
897+
898+ A redirecting generative constructor marked ` augment ` adds its redirecting
899+ initializer to the augmented constructors initializer list.
900+
901+ This converts it into a redirecting generative constructor, removing the
902+ potentially non-redirecting property of the constructor.
903+
904+ It is a compile-time error if:
905+
906+ * The augmented constructor has any initializers or a body.
907+
908+ #### Redirecting factory constructors
909+
910+ A redirecting factory constructor marked ` augment ` adds its factory redirection
911+ to the augmented constructor.
912+
913+ The result of applying the augmenting constructor is a redirecting factory
914+ constructor with the same target constructor designation as the augmenting
915+ constructor. This removes the potentially non-redirecting property of the
916+ constructor.
917+
918+ It is a compile-time error if:
919+
920+ * The augmented constructor has a body.
921+
922+ #### Extension types
832923
833924When augmenting an extension type declaration, the parenthesized clause where
834925the representation type is specified is treated as a constructor that has a
0 commit comments