New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement copy constructor #8688
Merged
Merged
Changes from all commits
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
3e77e7a
Parse copy constructor
RazvanN7 65b3605
Semantic analysis of copy constructor
RazvanN7 0d561a2
Lower AssignExp to copyCtor call
RazvanN7 c96eeb6
Add errors messages for wrong usage of implicit and copy ctor with po…
RazvanN7 3c34b2b
Implement copy consutructor call for arameter passing and function re…
RazvanN7 e3b4d49
Implement generation of copy constructors
RazvanN7 bcf8820
Implement opAssign generation
RazvanN7 f19669a
Add tests
RazvanN7 530791a
Make structs with copy ctor non-pod
RazvanN7 14a8117
Fix astbase + line number in tests
RazvanN7 3434b7a
Update .h files
RazvanN7 9c63f4d
Address feedback comments
RazvanN7 02fea7a
[WIP] Remove implicit
RazvanN7 2e97c40
Fix function overload resolution
RazvanN7 908b1e9
Postblit precedence
RazvanN7 1214ce6
Fix error message for argument with copy constructor
RazvanN7 ec0d6f9
Add copy ctor generation without implicit
RazvanN7 b85d853
Delete wrongfully added code from rebase
RazvanN7 912c304
Remove last traces of implicit + update .h files
RazvanN7 0bdd807
Add scope parameter to all callMatch calls in dmd/dtemplate.d
RazvanN7 95f2e59
Delete generation of opAssign and tweak generation of field copy cons…
RazvanN7 69b1cea
Add possiblity of defining default parameters for copy constructors
RazvanN7 a9e4c1d
Modify generation of copy constructors to match the DIP
RazvanN7 7c07c3f
solve mir failure
RazvanN7 30ffb88
Address feedback
RazvanN7 af93051
Delete isCopyCtor method
RazvanN7 db88573
Make definition of both rvalue constructor and copy constructor an error
RazvanN7 4410417
Add changelog entry
RazvanN7 95777c2
Add return scope for generated copy constructor parameter
RazvanN7 1aeffd1
Address feedback
RazvanN7 17b174c
Fix changelog + add tests
RazvanN7 File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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,179 @@ | ||
Copy Constructor | ||
|
||
With this release, the D language compiler implements the full functionality of the | ||
copy constructor described extensively in this DIP [1]. | ||
|
||
$(P Copy constructors are used to initialize a `struct` instance from | ||
another `struct` of the same type.) | ||
|
||
$(P A constructor declaration is a copy constructor declaration if and only if it is a constructor | ||
declaration that takes only one non-default parameter by reference that is | ||
of the same type as `typeof(this)`, followed by any number of default parameters:) | ||
|
||
--- | ||
struct A | ||
{ | ||
this(ref return scope A rhs) {} // copy constructor | ||
this(ref return scope const A rhs, int b = 7) {} // copy constructor with default parameter | ||
} | ||
--- | ||
|
||
$(P The copy constructor is type checked as a normal constructor.) | ||
|
||
$(P If a copy constructor is defined, implicit calls to it will be inserted | ||
in the following situations:) | ||
|
||
$(OL | ||
$(LI When a variable is explicitly initialized:) | ||
--- | ||
struct A | ||
{ | ||
this(ref return scope A rhs) {} | ||
} | ||
|
||
void main() | ||
{ | ||
A a; | ||
A b = a; // copy constructor gets called | ||
} | ||
--- | ||
|
||
$(LI When a parameter is passed by value to a function:) | ||
--- | ||
struct A | ||
{ | ||
this(ref return scope A another) {} | ||
} | ||
|
||
void fun(A a) {} | ||
|
||
void main() | ||
{ | ||
A a; | ||
fun(a); // copy constructor gets called | ||
} | ||
--- | ||
|
||
$(LI When a parameter is returned by value from a function and Named Returned Value Optiomization (NRVO) | ||
cannot be performed:) | ||
--- | ||
struct A | ||
{ | ||
this(ref return scope A another) {} | ||
} | ||
|
||
A fun() | ||
{ | ||
A a; | ||
return a; // NRVO, no copy constructor call | ||
} | ||
|
||
A a; | ||
A gun() | ||
{ | ||
return a; // cannot perform NRVO, rewrite to: return (A __tmp; __tmp.copyCtor(a)); | ||
} | ||
|
||
void main() | ||
{ | ||
A a = fun(); | ||
A b = gun(); | ||
} | ||
--- | ||
) | ||
|
||
$(P When a copy constructor is defined for a `struct`, all | ||
implicit blitting is disabled for that `struct`: | ||
) | ||
--- | ||
struct A | ||
{ | ||
int[] a; | ||
this(ref return scope A rhs) {} | ||
} | ||
|
||
void fun(immutable A) {} | ||
|
||
void main() | ||
{ | ||
immutable A a; | ||
fun(a); // error: copy constructor cannot be called with types (immutable) immutable | ||
} | ||
--- | ||
|
||
$(P The copy constructor can be overloaded with different qualifiers applied | ||
to the parameter (copying from a qualified source) or to the copy constructor | ||
itself (copying to a qualified destination): | ||
) | ||
--- | ||
struct A | ||
{ | ||
this(ref return scope A another) {} // 1 - mutable source, mutable destination | ||
this(ref return scope immutable A another) {} // 2 - immutable source, mutable destination | ||
this(ref return scope A another) immutable {} // 3 - mutable source, immutable destination | ||
this(ref return scope immutable A another) immutable {} // 4 - immutable source, immutable destination | ||
} | ||
|
||
void main() | ||
{ | ||
A a; | ||
immutable A ia; | ||
|
||
A a2 = a; // calls 1 | ||
A a3 = ia; // calls 2 | ||
immutable A a4 = a; // calls 3 | ||
immutable A a5 = ia; // calls 4 | ||
} | ||
--- | ||
|
||
$(P The `inout` qualifier may be applied to the copy constructor parameter in | ||
order to specify that mutable, `const`, or `immutable` types are treated the same: | ||
) | ||
--- | ||
struct A | ||
{ | ||
this(ref return scope inout A rhs) immutable {} | ||
} | ||
|
||
void main() | ||
{ | ||
A r1; | ||
const(A) r2; | ||
immutable(A) r3; | ||
|
||
// All call the same copy constructor because `inout` acts like a wildcard | ||
immutable(A) a = r1; | ||
immutable(A) b = r2; | ||
immutable(A) c = r3; | ||
} | ||
--- | ||
|
||
$(P A copy constructor is generated implicitly by the compiler for a `struct S` | ||
if all of the following conditions are met:) | ||
|
||
$(OL | ||
$(LI `S` does not explicitly declare any copy constructors;) | ||
$(LI `S` defines at least one direct member that has a copy constructor, and that | ||
member is not overlapped (by means of `union`) with any other member.) | ||
) | ||
|
||
$(P If the restrictions above are met, the following copy constructor is generated:) | ||
--- | ||
this(ref return scope inout(S) src) inout | ||
{ | ||
foreach (i, ref inout field; src.tupleof) | ||
this.tupleof[i] = field; | ||
} | ||
--- | ||
|
||
$(P If the generated copy constructor fails to type check, it will receive the `@disable` attribute.) | ||
|
||
$(P f an `union S` has fields that define a copy constructor, whenever an object of type `S` | ||
is initialized by copy, an error will be issued. The same rule applies to overlapped fields | ||
(anonymous unions).) | ||
|
||
$(P A `struct` that defines a copy constructor is not a POD.) | ||
|
||
[1] https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1018.md | ||
|
||
|
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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Parameters with default values are usually not allowed in DMD.