Bug 22614 – Wrong copy constructor is called depending on context

Status
NEW
Severity
blocker
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2021-12-20T20:50:53Z
Last change time
2024-12-13T19:19:58Z
Assigned to
No Owner
Creator
Stanislav Blinov
See also
https://issues.dlang.org/show_bug.cgi?id=16500
Moved to GitHub: dmd#20026 →

Comments

Comment #0 by stanislav.blinov — 2021-12-20T20:50:53Z
@safe // <- comment this @safe, and both asserts pass unittest { static struct S { int i; this(int i) { this.i = i; } this(ref const S) { i = 2; } this(ref S) immutable { i = 3; } } auto source = S(1); auto implicit = source; S explicit; explicit.__ctor(source); assert(implicit.i == 2); assert(explicit.i == 2); } This is blocking implementation of dup/idup for arrays that would correctly support copy constructors. (The unittest is actually adapted from existing one in druntime).
Comment #1 by razvan.nitu1305 — 2021-12-21T10:51:03Z
It seems that for some reason annotating with @safe the unittest enables the compiler to infer attributes for the nested struct members. This has the result of inferring pure for the copy constructors and therefore the immutable constructor becomes a unique constructor (which means it can be implicitly convertible to mutable). Next, the compiler thinks that the unique copy constructor is better than const copy constructor. I think that the fundamental problem here is that @safe enables attribute inference. I haven't seen this anywhere explicitly stated in the spec. The unique conversion rules are another black box for me.
Comment #2 by timon.gehr — 2022-01-14T16:14:01Z
(In reply to RazvanN from comment #1) > It seems that for some reason annotating with @safe the unittest enables the > compiler to infer attributes for the nested struct members. This has the > result of inferring pure for the copy constructors and therefore the > immutable constructor becomes a unique constructor (which means it can be > implicitly convertible to mutable). In general, unique `immutable` values _cannot_ convert to mutable. Therefore, I do not understand why the behavior would change here. The struct is convertible to mutable because there are no mutable indirections, it should not matter whether or not the copy constructors are pure. > Next, the compiler thinks that the > unique copy constructor is better than const copy constructor. > > I think that the fundamental problem here is that @safe enables attribute > inference. I haven't seen this anywhere explicitly stated in the spec. > ... That's a problem, but clearly the code should work even if annotated `pure`, so it does not seem like this is the _fundamental_ issue. > The unique conversion rules are another black box for me. Unique values should be able to implicitly convert to `immutable`, but that's it.
Comment #3 by robert.schadek — 2024-12-13T19:19:58Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/20026 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB