www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 22498] New: auto ref function with auto ref parameter causes


          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) {
    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(42) <- this is a copy (that shouldn't exist) being destroyed

But it should't compile as output from `gen()` is rvalue.
`__traits(isRef, res)` yields false in `unwrap` as expected, same with

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

Nov 09 2021