Bug 17346 – Inconsistent l/rvalue overload resolution

Status
NEW
Severity
normal
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2017-04-24T14:21:07Z
Last change time
2024-12-13T18:52:03Z
Assigned to
No Owner
Creator
ZombineDev
Moved to GitHub: dmd#19247 →

Comments

Comment #0 by petar.p.kirov — 2017-04-24T14:21:07Z
As Steven mentioned in this forum post [1], given an overload that varies solely on ref, then rvalue arguments should go to the non-ref and lvalue arguments should go to the ref. A simple test indicates that the above rule is true, but only if the ref overload is non-const: struct X { int x; } struct Y1 { this(X x) { writeln("rvalue: ", x.x); } this(const ref X x) // const { writeln("const lvalue ref: ", x.x); } } struct Y2 { this(X x) { writeln("rvalue: ", x.x); } this(ref X x) // non-const { writeln("lvalue ref: ", x.x); } } import std.stdio; void main() { auto y1_rval = Y1(X(1)); auto x1_lval = X(2); auto y1_lval = Y1(x1_lval); // should call the ref-overload auto y2_rval = Y2(X(3)); auto x2_lval = X(4); auto y2_lval = Y2(x2_lval); // should call the ref-overload } Expected output: Rvalue: 1 const lvalue ref: 2 Rvalue: 3 Lvalue ref: 4 Actual output: Rvalue: 1 Rvalue: 2 Rvalue: 3 Lvalue ref: 4 [1]: http://forum.dlang.org/post/[email protected]
Comment #1 by schveiguy — 2017-04-24T20:20:24Z
It does work with inout. Perhaps the reason it doesn't work is because it might view calling Y1(x1_lval) as Y1(cast(const)x1_lval) which seems to be an rvalue. But clearly there is no double indirection here, and if you remove the non-ref constructor, the const ref one is then chosen.
Comment #2 by robert.schadek — 2024-12-13T18:52:03Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/19247 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB