Bug 17415 – std.conv.emplace does not forward arguments correctly

Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
x86_64
OS
All
Creation time
2017-05-20T23:04:45Z
Last change time
2021-08-04T20:46:41Z
Assigned to
Eduard Staniloiu
Creator
Stanislav Blinov

Comments

Comment #0 by stanislav.blinov — 2017-05-20T23:04:45Z
import std.conv : emplace; struct S { @disable this(this); } class C { this(S) {} } void[__traits(classInstanceSize, C)] holder = 0; emplace!C(S.init); I'd expect that to compile, and move the initializer correctly. But it does not compile (static assert), because emplace() copies arguments around, instead of using something like std.functional.forward. However, the fix is not trivial, some of the Phobos code actually depends on this, whether intentionally or accidentally, I cannot tell.
Comment #1 by stanislav.blinov — 2017-05-20T23:05:21Z
Obviously, should be: emplace!C(holder, S.init);
Comment #2 by edi33416 — 2017-10-04T13:24:48Z
I might be wrong, but since you are disabling the postblit wouldn't you want to define the class ctor as: class C { this(const ref S) { /* magic */ } }
Comment #3 by andrei — 2017-10-16T13:07:39Z
S.init counts as an rvalue. We should treat it for all purposes the same as: struct S { S init(); ... } The way the value is produced does not entail a copy. Then the rvalue is moved into the constructor of C, so the code is legit.
Comment #4 by kinke — 2021-02-18T08:16:06Z
Comment #5 by kinke — 2021-08-04T20:46:41Z
Works since v2.096.