@@ -464,7 +464,7 @@ void test(int i)
464464$(H2 $(LEGACY_LNAME2 StructLiteral, struct-literal, Struct Literals))
465465
466466 $(P A struct literal consists of the name of the struct followed
467- by a parenthesized argument list:)
467+ by a parenthesized named argument list:)
468468
469469 $(SPEC_RUNNABLE_EXAMPLE_RUN
470470 ---
@@ -473,31 +473,58 @@ $(H2 $(LEGACY_LNAME2 StructLiteral, struct-literal, Struct Literals))
473473 int foo(S s) { return s.x; }
474474
475475 foo( S(1, 2) ); // set field x to 1, field y to 2
476+ foo( S(y: 2, x: 1) ); // same as above
476477 ---
477478 )
478479
479480 $(P Struct literals are syntactically like function calls.
480- If a struct has a member function named $(CODE opCall), then
481+ If a struct has a $(RELATIVE_LINK2 struct-constructor, Constructor)
482+ or a member function named `opCall`, then
481483 struct literals for that struct are not possible. See also
482484 $(DDSUBLINK spec/operatoroverloading, FunctionCall, opCall operator overloading)
483485 for the issue workaround.)
484486 $(P
485- It is an error if there are more arguments than fields of
486- the struct.
487- If there are fewer arguments than fields, the remaining
488- fields are initialized with their respective default
489- initializers.)
487+ If the first argument has no name, it will be assigned to the struct field that is defined first lexically.
488+ )
489+ $(P
490+ A named argument is assigned to the struct field with the same name.
491+ It is an error if no such field exists.
492+ )
493+ $(P
494+ Any other argument is assigned to the next lexically defined struct field relative to the preceding argument's struct field.
495+ It is an error if no such field exists, i.e. when the preceding argument assigns to the last struct field.
496+ )
497+ $(P
498+ It is also an error to assign a field more than once.
499+ )
490500 $(P
491- If there is a union field in the struct, only the first
501+ Any fields not assigned a value are initialized with their respective default initializers.
502+ )
503+ $(NOTE
504+ These rules are consistent with function calls, see $(DDSUBLINK spec/function, argument-parameter-matching, Matching Arguments to Parameters).
505+ )
506+ $(P
507+ If there is a union field in the struct, only one
492508 member of the union can be initialized inside a
493509 struct literal. This matches the behaviour for union literals.
494510 )
495511
512+ $(SPEC_RUNNABLE_EXAMPLE_FAIL
513+ ---
514+ struct S { int x = 1; int y = 2, int z = 3; }
515+
516+ S s0 = S(y: 5, 6, x: 4); // `6` is assigned to field `z`, which comes after `y`
517+ S s1 = S(y: 5, z: 6); // Field x is not assigned, set to default initializer `1`
518+ S s2 = S(y: 5, x: 4, 5); // Error: field `y` is assigned twice
519+ S s3 = S(z: 2, 3); // Error: no field beyond `z`
520+ ---
521+ )
522+
496523$(H2 $(LNAME2 union-literal, Union Literals))
497524
498- $(P A union literal is like a struct literal, but only the first field can
499- be initialized with an initializer expression. Any field larger than the
500- first will have the remainder of its memory initialized to zero.
525+ $(P A union literal is like a struct literal, but only one field can
526+ be initialized with an initializer expression.
527+ The remainder of the union's memory is initialized to zero.
501528 )
502529
503530$(SPEC_RUNNABLE_EXAMPLE_RUN
@@ -657,6 +684,21 @@ $(H2 $(LEGACY_LNAME2 Struct-Constructor, struct-constructor, Struct Constructors
657684 ---
658685 )
659686
687+ $(P Named arguments will be forwarded to the constructor and match parameter names, not struct field names.)
688+
689+ $(SPEC_RUNNABLE_EXAMPLE_FAIL
690+ ---
691+ struct S
692+ {
693+ int x;
694+ int y;
695+ this(int y, int z) { this.x = y; this.y = z; }
696+ }
697+ S a = S(x: 3, y: 4); // Error: constructor has no parameter named `x`
698+ S b = S(y: 3, 4); // `y: 3` will set field `x` through parameter `y`
699+ ---
700+ )
701+
660702 $(P A $(I default constructor) (i.e. one with an empty $(GLINK2 function, ParameterList))
661703 is not allowed.)
662704
0 commit comments