[Issue 22498] New: auto ref function with auto ref parameter causes noncopyable payload be cleaned twice
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Tue Nov 9 19:28:09 UTC 2021
https://issues.dlang.org/show_bug.cgi?id=22498
Issue ID: 22498
Summary: auto ref function with auto ref parameter causes
noncopyable payload be cleaned twice
Product: D
Version: D2
Hardware: x86_64
OS: Linux
Status: NEW
Severity: critical
Priority: P1
Component: dmd
Assignee: nobody at puremagic.com
Reporter: chalucha at gmail.com
With a code like
```
import core.lifetime : forward;
import core.stdc.stdio;
import std.algorithm : move;
struct Value(T) {
private T storage;
this()(auto ref T val) {
storage = forward!val;
}
ref inout(T) get() inout {
return storage;
}
}
Value!T value(T)(auto ref T val) {
return Value!T(forward!val);
}
auto ref unwrap(EX)(auto ref EX res) {
printf("unwrap()\n");
return res.get();
}
struct Foo {
int n;
@disable this(this);
~this() { printf("~this(%d)\n", n); }
}
auto gen() {
Foo f;
f.n = 42;
return value(f.move());
}
void main() {
Foo f;
f = gen().unwrap.move;
}
```
`unwrap` accepts copy of non copyable `Value!Foo` that results in this output:
```
~this(0)
~this(0)
~this(0)
unwrap()
~this(42) <- this is a copy (that shouldn't exist) being destroyed
~this(0)
~this(42)
```
But it should't compile as output from `gen()` is rvalue.
`__traits(isRef, res)` yields false in `unwrap` as expected, same with
`isCopyable!(Value!Foo)`.
Or is NRVO working even when return value is passed as a value to the `unwrap`?
But then why wouldn't unwrap.move() cause the payload to be reset?
And is it ok to ref being returned from `unwrap` when it's from local value
parameter?
--
More information about the Digitalmars-d-bugs
mailing list