-
-
Notifications
You must be signed in to change notification settings - Fork 609
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #8167 from RazvanN7/Issue_18719
Fix Issue 18719 - Doubly-called constructor against member when using forwarding constructors merged-on-behalf-of: Andrei Alexandrescu <andralex@users.noreply.github.com>
- Loading branch information
Showing
5 changed files
with
109 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| Deprecate double initialization of immutable fields inside constructor | ||
|
|
||
| Inside a constructor scope, assigning to aggregate declaration (class/struct) | ||
| members is done by considering the first assignment as initialization and | ||
| subsequent assignments as modifications of the initially constructed object. | ||
| For `const`/`immutable` fields the initialization is accepted in the constructor, | ||
| but subsequent modifications are not. Example: | ||
|
|
||
| --- | ||
| struct A | ||
| { | ||
| int a; | ||
| immutable int b; | ||
| this(int a, int b) | ||
| { | ||
| this.a = a; | ||
| this.b = b; | ||
|
|
||
| this.a = 7; // OK, a is mutable | ||
| this.b = 9; // Error: immutable field b initialized multiple times | ||
| } | ||
| } | ||
| --- | ||
|
|
||
| However, $(BUGZILLA 18719) shows that this rule does not apply when inside | ||
| a constructor scope there is a call to a different constructor: | ||
|
|
||
| --- | ||
| struct A | ||
| { | ||
| immmutable int a; | ||
| this() | ||
| { | ||
| this(42); | ||
| this.a = 5; // second initialization of immutable field | ||
| } | ||
|
|
||
| this(int a) | ||
| { | ||
| this.a = a; | ||
| } | ||
| } | ||
| --- | ||
|
|
||
| The above code wrongfully compiled succesfully before this patch, accepting the double | ||
| initialization of the `immutable` field `a`. After this patch, `this.a = 5` will issue | ||
| a deprecation warning stating that `a` is initialized multiple times. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| // https://issues.dlang.org/show_bug.cgi?id=18719 | ||
|
|
||
| // REQUIRED_ARGS: -de | ||
| /* | ||
| TEST_OUTPUT: | ||
| --- | ||
| fail_compilation/fail18719.d(29): Deprecation: immutable field `x` initialized multiple times | ||
| --- | ||
| */ | ||
|
|
||
| struct S | ||
| { | ||
| int x = -1; | ||
| this(int y) immutable | ||
| { | ||
| x = y; | ||
| import std.stdio; | ||
| writeln("Ctor called with ", y); | ||
| } | ||
| void opAssign(int) immutable; | ||
| } | ||
|
|
||
| class C | ||
| { | ||
| S x; | ||
| this() immutable | ||
| { | ||
| this(42); /* Initializes x. */ | ||
| x = 13; /* Breaking immutable, or ok? */ | ||
| } | ||
| this(int x) immutable | ||
| { | ||
| this.x = x; | ||
| } | ||
| } | ||
|
|
||
| void main() | ||
| { | ||
| new immutable C; | ||
| } |