Summary: out contracts fail with ref return types
           Product: D
           Version: 2.041
          Platform: Other
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD

--- Comment #0 from Luther Tychonievich <> 2010-03-15 
20:23:53 PDT ---
The following does not compile:
ref int buggy(ref int x) 
out(result){ }
body { return ++x; }
bug.d(3): Error: result = (x += 1) is not mutable
bug.d(3): Error: result = (x += 1) is not an lvalue

The first of these statements comes because out contracts are always const
(func.c:1111) and thus not mutable.
The second comes from statement:3488 where we try to make an assignment
expression (created on statement.c:3490) into an lvalue, which assignment
expressions are not.

Reading through the source, I think what is going on is that
    out(x) { Y }
    return Z
is replaced with
    const nonref typeof(return) x; // statment.c:3488, func.c:1107..1124
    lvalue(x = Z);  // statement.c:3490, 3500
    goto __returnLabel; // statement.c:3536
    void __ensure(ref typeof(return) x) { Y } // func.c:713..738
I probably got some of this wrong; I'm not familiar with most of this code.

It's not clear to me why we don't instead do
    typeof(return) __ensure(const typeof(return) x) { Y cast(typeof(return))x;
    return __ensure( Z )
which seems at least superficially simpler.

I discovered this issue while trying to understand issue 3667, and suspect
without evidence that the two might be related.

Configure issuemail:
------- You are receiving this mail because: -------

Reply via email to