Binding rvalues to ref parameters redux

Olivier FAURE couteaubleu at gmail.com
Fri Mar 29 19:43:16 UTC 2019


On Friday, 29 March 2019 at 12:16:40 UTC, Andrei Alexandrescu 
wrote:
> I could change the DIP to require lvalues throughout. Also, we 
> should probably change the language to disallow other 
> constructs as well. Essentially I think a.b.c should be an 
> rvalue (even if it's ostensibly an lvalue) if any of a, b, or c 
> is an rvalue.

Yes please.

> I have moved that part straight into the specification of 
> lvalues and rvalues. "this" in struct and union types is an 
> lvalue. In classes it's an rvalue.

That's not what I meant. What I meant is

     getFoo(...).applyDiscount(...)

should behave the same way whether applyDiscount is a method 
taking a Foo as its 'this' parameter, or a global function taking 
a Foo as its first parameter.

>>      int getGraphSize(ref Node);
>>      Node makeNode(int x);
>>      Node makeNode(return ref Node child1, return ref Node 
>> child2);
>> 
>>      // Probably should compile
>>      getGraphSize(makeNode(makeNode(1), makeNode(2)));
>> 
>>      // Probably should not
>>      auto persistentNode = makeNode(makeNode(1), makeNode(2));
>>      // Invalid write
>>      persitentNode.child1.x = 123;
>
> Did you mean makeNode to return by reference?

No, I meant something like that:

     struct Node {
         Node* child1;
         Node* child2;
         int x;
     }

     Node makeNode(return ref Node child1, return ref Node child2) 
@safe {
         Node newNode = { &child1, &child2 };
         return newNode;
     }

This currently compiles with -dip1000.

Generally speaking, I think any function called with a rvalue as 
a 'return ref' argument should be considered as returning a 
rvalue.

The "a.b.c is a rvalue if a, b, or c is a rvalue" rule could be 
considered a special case of that principle.


More information about the Digitalmars-d mailing list