www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - simple DIP1000 test fails?

reply Q. Schroll <qs.il.paperinik gmail.com> writes:
I've tried to get into the changes by DIP1000 and discovered this:

struct S { ref S id() return { return this; } }
void main() { S* p = &S().id(); }

Should it really compile? (rdmd -dip1000 .\test_return_ref.d)
Nov 02
next sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Thursday, November 02, 2017 19:53:36 Q. Schroll via Digitalmars-d-learn 
wrote:
 struct S { ref S id() return { return this; } }
 void main() { S* p = &S().id(); }
Well, if you make them safe, it won't compile whether -dip1000 is used or not. At the moment, I don't recall whether -dip1000's effects are supposed to be limited to safe code or not though. If they are, then I don't think that there's a bug, but if they aren't, then it looks like there is. - Jonathan M Davis
Nov 02
prev sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Thursday, November 02, 2017 14:03:52 Jonathan M Davis via Digitalmars-d-
learn wrote:
 On Thursday, November 02, 2017 19:53:36 Q. Schroll via Digitalmars-d-learn
 wrote:
 struct S { ref S id() return { return this; } }
 void main() { S* p = &S().id(); }
Well, if you make them safe, it won't compile whether -dip1000 is used or not. At the moment, I don't recall whether -dip1000's effects are supposed to be limited to safe code or not though. If they are, then I don't think that there's a bug, but if they aren't, then it looks like there is.
Though actually, scope isn't used anywhere here, and IIRC, -dip1000 only comes into affect when scope is used. So, I don't think that -dip1000 really applies here. But I'm not as well-versed in the ins and outs of DIP 1000 as I should be, so I could be wrong. - Jonathan M Davis
Nov 02
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 11/2/17 4:07 PM, Jonathan M Davis wrote:
 On Thursday, November 02, 2017 14:03:52 Jonathan M Davis via Digitalmars-d-
 learn wrote:
 On Thursday, November 02, 2017 19:53:36 Q. Schroll via Digitalmars-d-learn
 wrote:
 struct S { ref S id() return { return this; } }
 void main() { S* p = &S().id(); }
Well, if you make them safe, it won't compile whether -dip1000 is used or not. At the moment, I don't recall whether -dip1000's effects are supposed to be limited to safe code or not though. If they are, then I don't think that there's a bug, but if they aren't, then it looks like there is.
Though actually, scope isn't used anywhere here, and IIRC, -dip1000 only comes into affect when scope is used. So, I don't think that -dip1000 really applies here. But I'm not as well-versed in the ins and outs of DIP 1000 as I should be, so I could be wrong.
The issue here is that rvalues bind to the `this` reference. I think this is actually dip25, and it's definitely a bug. Whatever kicks in when dip25 is enabled (tried -dip25 and -dip1000 switch, and it still compiles) is not understanding the lifetime of the rvalue in order to properly apply it to the resulting ref. -Steve
Nov 02
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Thursday, November 02, 2017 16:39:43 Steven Schveighoffer via 
Digitalmars-d-learn wrote:
 On 11/2/17 4:07 PM, Jonathan M Davis wrote:
 On Thursday, November 02, 2017 14:03:52 Jonathan M Davis via
 Digitalmars-d->
 learn wrote:
 On Thursday, November 02, 2017 19:53:36 Q. Schroll via
 Digitalmars-d-learn>>
 wrote:
 struct S { ref S id() return { return this; } }
 void main() { S* p = &S().id(); }
Well, if you make them safe, it won't compile whether -dip1000 is used or not. At the moment, I don't recall whether -dip1000's effects are supposed to be limited to safe code or not though. If they are, then I don't think that there's a bug, but if they aren't, then it looks like there is.
Though actually, scope isn't used anywhere here, and IIRC, -dip1000 only comes into affect when scope is used. So, I don't think that -dip1000 really applies here. But I'm not as well-versed in the ins and outs of DIP 1000 as I should be, so I could be wrong.
The issue here is that rvalues bind to the `this` reference. I think this is actually dip25, and it's definitely a bug. Whatever kicks in when dip25 is enabled (tried -dip25 and -dip1000 switch, and it still compiles) is not understanding the lifetime of the rvalue in order to properly apply it to the resulting ref.
Except that IIRC, DIP 25 only applies to safe code. I haven't read DIP 25 recently, but I assume that the return on id is equivalent to marking the this parameter with return, in which case, the compiler knows where the returned reference came from. So, returning by ref shouldn't be a problem. The problem is simply taking the address, since the S is a temporary, and that's already caught by safe even without compiling with -dip25. So, unless I'm remembering wrong, and -dip25 actually applies to system code as well, then I don't think that this is a bug in -dip25. - Jonathan M Davis
Nov 02
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 11/2/17 6:10 PM, Jonathan M Davis wrote:
 Except that IIRC, DIP 25 only applies to  safe code.
I think the original implementation only applied to safe code, but it seems to have an effect on system code as well: Stevens-MacBook-Pro:testd steves$ cat testdip25.d ref int foo(ref int s) { return s; } void main() { int i; int *p = &foo(i); } Stevens-MacBook-Pro:testd steves$ dmd testdip25.d Stevens-MacBook-Pro:testd steves$ dmd -dip25 testdip25.d testdip25.d(3): Error: returning s escapes a reference to parameter s, perhaps annotate with return
 I haven't read DIP 25
 recently, but I assume that the return on id is equivalent to marking the
 this parameter with return, in which case, the compiler knows where the
 returned reference came from. So, returning by ref shouldn't be a problem.
 The problem is simply taking the address, since the S is a temporary, and
 that's already caught by  safe even without compiling with -dip25.
Right, the whole point of 'return' is to tell the compiler that the 'this' parameter is getting returned. IMO, this shouldn't even work on rvalues. It's not even the taking of the address, it's the fact that the address of the result outlives the rvalue. The compiler should be able to tell that if I call id with an rvalue, the resulting reference can't escape the expression. So it's somewhat of a cross between dip1000 and dip25, but obviously neither flags it. -Steve
Nov 02
parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Thursday, November 02, 2017 18:54:15 Steven Schveighoffer via 
Digitalmars-d-learn wrote:
 On 11/2/17 6:10 PM, Jonathan M Davis wrote:
 I haven't read DIP 25
 recently, but I assume that the return on id is equivalent to marking
 the
 this parameter with return, in which case, the compiler knows where the
 returned reference came from. So, returning by ref shouldn't be a
 problem. The problem is simply taking the address, since the S is a
 temporary, and that's already caught by  safe even without compiling
 with -dip25.
Right, the whole point of 'return' is to tell the compiler that the 'this' parameter is getting returned. IMO, this shouldn't even work on rvalues. It's not even the taking of the address, it's the fact that the address of the result outlives the rvalue. The compiler should be able to tell that if I call id with an rvalue, the resulting reference can't escape the expression. So it's somewhat of a cross between dip1000 and dip25, but obviously neither flags it.
I would think that it would be fine if you simply called a member function on the rvalue. You couldn't pass the rvalue to any function accepting ref, so the ref return would largely be pointless, but allowing a member function to be called on the ref returned rvalue would mean that you could still use the member function that returned by ref with an rvalue, whereas otherwise, you'd be forced to assign it to a variable, which wouldn't be the end of the world, but it would lose out on some flexibility that technically should work just fine. But I don't think that there's any question that what's allowed with that ref return needs to be more restricted, since doing something like taking its address or passing it to a free function that accepts by ref would be really bad, and if disallowing calling ref return functions on rvalues was the most reasonable way to stop that, then it wouldn't be the end of the world. - Jonathan M Davis
Nov 02