March 29, 2020 [Issue 20706] New: `-preview=rvaluerefparam` does not work with copy constructor (and should do NRVO) | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=20706 Issue ID: 20706 Summary: `-preview=rvaluerefparam` does not work with copy constructor (and should do NRVO) Product: D Version: D2 Hardware: All OS: All Status: NEW Keywords: industry Severity: normal Priority: P1 Component: dmd Assignee: nobody@puremagic.com Reporter: pro.mathias.lang@gmail.com Consider the following code: ``` struct Foo { int a; @disable this(this); this(int a_) { this.a = a_; } this(const ref typeof(this) other) { this.a = other.a + 1; } } void bar (T) (const ref T arg) { assert(arg.a == 42); } void main () { bar!Foo(Foo(41)); } ``` This will trigger the following error message (DMD 2.091): ``` % dmd -preview=rvaluerefparam autoref.d autoref.d(13): Error: function autoref.bar!(Foo).bar(ref const(Foo) arg) is not callable using argument types (Foo) autoref.d(13): cannot pass rvalue argument Foo(0).this(42) of type Foo to parameter ref const(Foo) arg ``` This has many problems: 1) The error message is bad, because it doesn't explain why it's not possible (namely, because the postblit is disabled) 2) A copy constructor should always have priority over a postblit. If a copy constructor is present and the postblit disabled, the copy constructor should be called. Commenting out disabled postblit declaration will trigger the assert, because the copy ctor is indeed not called. 3) We should not need to have a copy here. What's the point of rvalue ref if it does a copy indiscriminately ? -- |
Copyright © 1999-2021 by the D Language Foundation