Bug 19872 – Copy constructor: Order of declaration yields different results with rvalue constructor

Status
RESOLVED
Resolution
DUPLICATE
Severity
blocker
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2019-05-14T14:44:23Z
Last change time
2019-05-14T16:04:55Z
Keywords
accepts-invalid, C++, rejects-valid, Vision
Assigned to
No Owner
Creator
Atila Neves

Comments

Comment #0 by atila.neves — 2019-05-14T14:44:23Z
The code below contains identical struct declarations except for the order of the constructors in the body. Yet, `Ok` compiles file and `Oops` does not: ---------------------- struct Ok { this(ref Ok other); this(Ok other); } struct Oops { this(Oops other); this(ref Oops other); } ---------------------- bug.d(7): Error: struct Oops may not define both a rvalue constructor and a copy constructor bug.d(8): rvalue constructor defined here bug.d(9): copy constructor defined here The order shouldn't make a difference on whether or not the code compiles, but nearly as importantly: *why* wouldn't one be able to declare both a copy constructor and an rvalue one? How else would one have both copy and move semantics?
Comment #1 by razvan.nitu1305 — 2019-05-14T15:25:50Z
See discussion here: https://github.com/dlang/dmd/pull/8688#discussion_r248601249 The patch for 19871 will solve this bug too.
Comment #2 by razvan.nitu1305 — 2019-05-14T15:27:17Z
Closing as duplicate of 19871. *** This issue has been marked as a duplicate of issue 19871 ***
Comment #3 by atila.neves — 2019-05-14T16:04:55Z
I added a comment in the discussion but will add it here as well: I missed this discussion originally. The reason one one wants to have: ```d struct Foo { this(ref Foo); this(Foo); } ``` is simple: C++ interop. I made it so that the dpp translations actually enabled D code to call a C++ move constructor by overloading on this. More importantly, D should be able to do what C++ does without needing rvalue references. So the equivalent of this should be possible: ----------------------- struct Foo { Foo(const Foo& foo); // copy ctor Foo(Foo&& foo); // move ctor }; ----------------------- As you can imagine, any and all types that have been updated post C++11 that had copy constructors now have move constructors, so...