digitalmars.dip.ideas - Rethink copy and move constructors
- Dejan Lekic (19/19) May 24 Please, instead of atrocities like `this(ref return scope
- Richard (Rikki) Andrew Cattermole (8/14) May 24 For D copy by default is the better solution, as it also applies to
- Dejan Lekic (12/19) May 24 OK. Copy by default it is!
- Richard (Rikki) Andrew Cattermole (5/28) May 24 The copy constructors and move constructor declaration has been
- libxmoc (4/23) May 25 +1, this is a much cleaner way of handling it.
- Timon Gehr (53/56) May 25 You forgot `inout`. Try this:
- c-smile (17/24) May 25 I am with you here too.
- Timon Gehr (19/29) May 26 It is:
- Dejan Lekic (2/7) May 26
Please, instead of atrocities like `this(ref return scope
typeof(this) rhs)`
can we, for the love of God, have simple
```d
this(MyType rhs) disable; // copy
this(MyType rhs) move { ... } // move
```
???
Even better, can we adopt Rust move-by-default strategy? This
deserves a DIP from someone smarter than me. Can we please get
rid of the super-buggy and super-ugly `this(ref return scope
typeof(this) rhs)` (I am losing words and can't find suitable
pejoratives) in favour of something that really makes sense, and
avoid humiliation from communities outside D as they really laugh
when they see this!
Or simply call them `copyThis` and `moveThis` or something, just
do not use this nonsense above that already somehow got into the
codebase, probably because whoever proposed is good friend of our
BDFL!
May 24
On 25/05/2026 2:44 AM, Dejan Lekic wrote:Even better, can we adopt Rust move-by-default strategy? This deserves a DIP from someone smarter than me. Can we please get rid of the super- buggy and super-ugly |this(ref return scope typeof(this) rhs)| (I am losing words and can't find suitable pejoratives) in favour of something that really makes sense, and avoid humiliation from communities outside D as they really laugh when they see this!For D copy by default is the better solution, as it also applies to pointers. However, to get us an ownership transfer system, we'd probably want a type qualifier based one. Like isolated from Midori. But before that can be added, we need a borrow checker to protect it, and with that a DFA engine that can be on by default. Which I'm actively working on.
May 24
On Sunday, 24 May 2026 at 16:12:44 UTC, Richard (Rikki) Andrew Cattermole wrote:For D copy by default is the better solution, as it also applies to pointers. However, to get us an ownership transfer system, we'd probably want a type qualifier based one. Like isolated from Midori. But before that can be added, we need a borrow checker to protect it, and with that a DFA engine that can be on by default. Which I'm actively working on.OK. Copy by default it is! - Can we please make those constructors (copy and move) for humans please? Or you do not want to do move at all and rely on the current D approach of automated move of things compiler can deduce as moveable? I am fine with that too if it is properly documented, so we know what to do! I wonder how many people from D community even know what is the right approach depending on a use-case here, considering how obscure is the current copy constructor signature, and the fact that disable this(this) takes precedence...
May 24
On 25/05/2026 6:28 AM, Dejan Lekic wrote:On Sunday, 24 May 2026 at 16:12:44 UTC, Richard (Rikki) Andrew Cattermole wrote:The copy constructors and move constructor declaration has been discussed quite extensively. As for calling it? A type qualifier would trigger it automatically, rather than the copy constructor.For D copy by default is the better solution, as it also applies to pointers. However, to get us an ownership transfer system, we'd probably want a type qualifier based one. Like isolated from Midori. But before that can be added, we need a borrow checker to protect it, and with that a DFA engine that can be on by default. Which I'm actively working on.OK. Copy by default it is! - Can we please make those constructors (copy and move) for humans please? Or you do not want to do move at all and rely on the current D approach of automated move of things compiler can deduce as moveable? I am fine with that too if it is properly documented, so we know what to do! I wonder how many people from D community even know what is the right approach depending on a use-case here, considering how obscure is the current copy constructor signature, and the fact that disable this(this) takes precedence...
May 24
On Sunday, 24 May 2026 at 14:44:51 UTC, Dejan Lekic wrote:
Please, instead of atrocities like `this(ref return scope
typeof(this) rhs)`
can we, for the love of God, have simple
```d
this(MyType rhs) disable; // copy
this(MyType rhs) move { ... } // move
```
???
Even better, can we adopt Rust move-by-default strategy? This
deserves a DIP from someone smarter than me. Can we please get
rid of the super-buggy and super-ugly `this(ref return scope
typeof(this) rhs)` (I am losing words and can't find suitable
pejoratives) in favour of something that really makes sense,
and avoid humiliation from communities outside D as they really
laugh when they see this!
Or simply call them `copyThis` and `moveThis` or something,
just do not use this nonsense above that already somehow got
into the codebase, probably because whoever proposed is good
friend of our BDFL!
+1, this is a much cleaner way of handling it.
I bet that whoever came up with the monstrosity that it is today
don't even use them, and probably no longer use D.
May 25
On 5/24/26 16:44, Dejan Lekic wrote:Can we please get rid of the super-buggy and super-ugly `this(ref return scope typeof(this) rhs)` (I am losing words and can't find suitable pejoratives)You forgot `inout`. Try this: ```d import std.range; struct S{ this(ref return scope S rhs){} } struct T{ S s; } void main(){ auto x=[T()].dup; } ``` This works: ```d import std.range; struct S{ this(ref return scope inout S rhs)inout{} } struct T{ S s; } void main(){ auto x=[T()].dup; } ``` Also, this still does not work (probably a bug): ```d import std.range; struct S{ this(ref S rhs){} } struct T{ S s; this(ref T rhs){ this.s = rhs.s; } } void main(){ auto x=[T()].dup; } ``` Anyway, ```d this(S rhs){} this(ref S rhs){} ``` actually makes quite a bit of sense to me, that seems sane. DIP1000? Not so much, but at least you do not have to bother with it if you don't want/need to check pointer escaping. Trying to push `inout` and/or `const` on unsuspecting users? That's the point where I too would reach for any suitable pejoratives. ;)
May 25
On Sunday, 24 May 2026 at 14:44:51 UTC, Dejan Lekic wrote:
Please, instead of atrocities like `this(ref return scope
typeof(this) rhs)`
can we, for the love of God, have simple
```d
this(MyType rhs) disable; // copy
this(MyType rhs) move { ... } // move
```
I am with you here too.
According to the Principle of Least Astonishment copy constructor
should be just this
```
this(ref S rhs) {...}
```
While move constructor is more rare so it is fine to have it as
```
this(ref S rhs) move {...}
```
Actually bumped into this in Sciter/D where I thought that
`this(ref S rhs)` is the copy CTOR.
Alternatively but worse IMO:
```
this(ref const S rhs) // copy constructor
```
May 25
On 5/26/26 06:04, c-smile wrote:Actually bumped into this in Sciter/D where I thought that `this(ref S rhs)` is the copy CTOR. ...It is: https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1018.mdInside a struct definition, a declaration is a copy constructordeclaration if it is a constructor declaration that takes the first parameter as a nondefaulted reference to the same type as the struct being defined. A constructor declaration is a copy constructor declaration if it meets the following requirements: https://dlang.org/spec/struct.html#struct-copy-constructor * It takes exactly one parameter without a default argument, followed by any number of parameters with default arguments. * Its first parameter is a ref parameter. * The type of its first parameter is the same type as typeof(this), optionally with one or more type qualifiers applied to it. * It is not a template constructor declaration. I don't know why `return scope` is used in all examples.Alternatively but worse IMO: ``` this(ref const S rhs) // copy constructor ```This is also a copy constructor under the current rules. If the suggestion is to _require_ `const`, then _of course not_, that makes no sense.
May 26
On Tuesday, 26 May 2026 at 09:46:04 UTC, Timon Gehr wrote:I don't know why `return scope` is used in all examples.I found it at the very bottom of the DIP document:The DIP was subsequently modified, with the consent of the Language Maintainers, to add return scope to the copy constructor parameter in the code snippets as an example of good practice.
May 26









"Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> 