[Issue 20706] New: `-preview=rvaluerefparam` does not work with copy constructor (and should do NRVO)

d-bugmail at puremagic.com d-bugmail at puremagic.com
Sun Mar 29 10:24:58 UTC 2020


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 at puremagic.com
          Reporter: pro.mathias.lang at 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 ?

--


More information about the Digitalmars-d-bugs mailing list