Bug 23681 – Generated copy constructors failing to generate

Status
RESOLVED
Resolution
DUPLICATE
Severity
minor
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2023-02-08T22:45:54Z
Last change time
2023-02-09T14:38:09Z
Assigned to
No Owner
Creator
Richard Cattermole

Comments

Comment #0 by alphaglosined — 2023-02-08T22:45:54Z
Copy constructors are failing to generate and be callable if a field is another struct that does define a copy constructor. This is quite frustrating for using reference counted types, resulting in more boiler plate than required. DMD32 D Compiler v2.101.0-dirty ```d void main() { Depender a, b; b = a; } struct Dependency { this(ref Dependency other) { this.tupleof = other.tupleof; } ~this() { } } struct Depender { Dependency dependency; } ``` Error: buggycopyctr.d(3): Error: generated function `buggycopyctr.Depender.opAssign(Depender p)` is not callable using argument types `(Depender)` buggycopyctr.d(3): generating a copy constructor for `struct Depender` failed, therefore instances of it are uncopyable Removing destructor from Dependency makes it compile. Adding an opAssign that takes Depender by ref also works: ```d void opAssign(ref Depender other) { this.tupleof = other.tupleof; } ``` I suspect this issue is strongly related to another issue with copy constructors I'm having: Error: generating an `inout` copy constructor for `struct sidero.base.logger.FileTarget` failed, therefore instances of it are uncopyable However I wasn't able to reproduce that error message, but I did come up with the above so it might be helpful to hunt it down.
Comment #1 by razvan.nitu1305 — 2023-02-09T14:38:09Z
When the copy constructor for Depender is generated it looks like: this(ref inout Depender src) inout { this.dependency = dependency; } However, this.dependency = dependency is rewritten to this.dependency.copyCtor(dependency); which cannot be called because it is mutable and we are using inout objects. Therefore the cpctor is marked as disable. The destructor of Dependency causes the compiler to generate an opAssign with the signature "ref Dependency opAssign(Dependency src)". The existence of this assignment operator causes Depender (which contains a Dependency) to also define an opAssign which receives the argument by value. That is where the generated (and disabled) copy constructor is called. This is another effect of what I described here: https://issues.dlang.org/show_bug.cgi?id=20876#c4 . Fixing 20876 to correctly generate more accurate copy constructors will also fix this. Another approach would be to stop generating assignment operators based on copy constructors and destructors. *** This issue has been marked as a duplicate of issue 20876 ***