digitalmars.D.bugs - [Issue 22498] New: auto ref function with auto ref parameter causes
- d-bugmail puremagic.com (68/68) Nov 09 2021 https://issues.dlang.org/show_bug.cgi?id=22498
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 puremagic.com Reporter: chalucha 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? --
Nov 09 2021