@@ -348,6 +348,96 @@ $(SECTION3 $(LEGACY_LNAME2 Struct-Constructor, struct-constructor, Struct Constr
348348 }
349349 ------
350350
351+ $(P Inside a constructor, the first occurrence (in lexical order) of assignments
352+ of the form $(CODE member = expression;) are handled differently than usual
353+ assignments. The first such assignment in lexical order is converted to a
354+ constructor call for the member's type. Example:)
355+
356+ ------
357+ import std.stdio;
358+
359+ struct A
360+ {
361+ this(int x) { writef("A.this(%s)", x); }
362+ }
363+
364+ struct B
365+ {
366+ A a;
367+ this(int x)
368+ {
369+ write("[= ");
370+ a = x;
371+ writeln(" =]");
372+ // a = x; does not compile here, it already occurred lexically.
373+ }
374+ }
375+
376+ void main(string[] args)
377+ {
378+ auto b = B(10);
379+ // b.a = 10; does not compile here, A does not define opAssign(int).
380+ }
381+ ------
382+
383+ $(P The program above prints the line $(CODE "[= A.this(10) =]"). Anywhere else
384+ attempting to assign an integer to an object of type `A` would count as an
385+ assignment (and is not compilable because `A` does not define `opAssign(int)`).)
386+
387+ $(P Finding the first assignment in lexical order is flow-sensitive upon the
388+ `if` statement. Consider a change to struct `B` in the previous example as
389+ follows:)
390+
391+ ------
392+ struct B
393+ {
394+ A a;
395+ this(int x)
396+ {
397+ if (x < 0)
398+ a = -x;
399+ else
400+ a = x;
401+ }
402+ }
403+ ------
404+
405+ $(P This code issues a constructor call on each branch of the `if` statement.
406+ However, such flow sensitivity is limited. There is no static or dynamic
407+ analysis of coverage of the `if` statement. For example:)
408+
409+ ------
410+ struct B
411+ {
412+ A a;
413+ this(int x)
414+ {
415+ if (false) a = 0; // constructor call even if never covered
416+ a = x; // error, cannot assign
417+ }
418+ }
419+ ------
420+
421+ $(P Also, member assignments inside loops are never considered constructors,
422+ even if it can be determined statically that the loop executes at most once.
423+ Example:)
424+
425+ ------
426+ struct B
427+ {
428+ A a;
429+ this(int x)
430+ {
431+ foreach (i; 0 .. x ? 0 : 1) a = i; // error, cannot assign
432+ }
433+ }
434+ ------
435+
436+ $(P If an exception is thrown at any point from within a constructor,
437+ destructors are called for all members, in reverse lexical order of their
438+ declaration. Members that have not been explicitly initialized in the
439+ constructor will have their `.init` values upon destruction.)
440+
351441 $(P A constructor qualifier allows the object to be constructed with
352442 that specific qualifier.
353443 )
0 commit comments