This code crashes the compiler since 2.086.0: ------------------ struct Struct { @disable this(); this(ref Struct other) { const Struct s = void; this(s); } this(Struct); } ------------------ It also issues this seemingly nonsensical error: bug.d(6): Error: variable `bug.Struct.this.__copytmp2` default construction is disabled for type Struct The intention of the code is to call the by-value constructor, which used to work.
The correct behavior here should be an error that you cannot define both the rvalue constructor and the lvalue constructor (copy constructor). For more information, see: https://github.com/dlang/dmd/pull/8688#discussion_r248601249
@RazvanN7 created dlang/dmd pull request #9792 "Fix Issue 19871 - Copy constructor rejects valid code if default construction is disabled" fixing this issue: - Fix Issue 19871 - Copy constructor rejects valid code if default construction is disabled https://github.com/dlang/dmd/pull/9792
*** Issue 19872 has been marked as a duplicate of this issue. ***
I disagree wholeheartedly that it should be the correct behaviour. I'm pasting the same comment again here so it doesn't get lost. 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. Which I'd declare in D how, exactly?
(In reply to Atila Neves from comment #4) > I disagree wholeheartedly that it should be the correct behaviour. I'm > pasting the same comment again here so it doesn't get lost. > > 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. Which I'd declare in D > how, exactly? Well, I think that the idea is that opPostMove (DIP1014) would be the solution.
dlang/dmd pull request #9792 "Fix Issue 19871 - Copy constructor rejects valid code if default construction is disabled" was merged into stable: - 14ae8a4a4bc39ffc1b1b416ece17e5edfc36f49d by RazvanN7: Fix Issue 19871 - Copy constructor rejects valid code if default construction is disabled https://github.com/dlang/dmd/pull/9792