www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - lifetime issue: Bug or not?

reply Steven Schveighoffer <schveiguy gmail.com> writes:
I have code in my proprietary project that looks like this:

struct X
{
    ...
    SQLStatement foo()
    {
       auto stmt = SQLStatement("`foo`"); // table
       return stmt.where("`id` = ?", id);
    }
}

where is a function that adds a where clause with a given value to the 
SQL statement. It takes an SQLStatement by ref, and returns that 
statement by ref.

Signature looks like this:

ref SQLStatement where(T)(return ref SQLStatement stmt, string clause, T 
val)

In this case, I'm using the convenience of returning the statement to 
return that from the function.

However, the compiler is complaining:

  Error: returning where(stmt, "`id` = ?", id) escapes a reference to 
local variable stmt

But... it's not returning a ref. So why the complaint?

I have to separate into 2 lines.

I tried to make a simple example to show the problem, but looks like it 
doesn't fail in that case.

Any ideas?

-Steve
Nov 22 2019
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2019-11-22 19:54, Steven Schveighoffer wrote:

 I tried to make a simple example to show the problem, but looks like it 
 doesn't fail in that case.
Can you run dustmite to create a reduced example? -- /Jacob Carlborg
Nov 22 2019
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 11/22/19 2:40 PM, Jacob Carlborg wrote:
 On 2019-11-22 19:54, Steven Schveighoffer wrote:
 
 I tried to make a simple example to show the problem, but looks like 
 it doesn't fail in that case.
Can you run dustmite to create a reduced example?
I can at some point. For now, I need to keep moving. Just wondering if others think it's a bug or not. -Steve
Nov 22 2019
prev sibling next sibling parent reply Meta <jared771 gmail.com> writes:
On Friday, 22 November 2019 at 18:54:49 UTC, Steven Schveighoffer 
wrote:
 I have code in my proprietary project that looks like this:

 struct X
 {
    ...
    SQLStatement foo()
    {
       auto stmt = SQLStatement("`foo`"); // table
       return stmt.where("`id` = ?", id);
    }
 }

 where is a function that adds a where clause with a given value 
 to the SQL statement. It takes an SQLStatement by ref, and 
 returns that statement by ref.

 Signature looks like this:

 ref SQLStatement where(T)(return ref SQLStatement stmt, string 
 clause, T val)

 In this case, I'm using the convenience of returning the 
 statement to return that from the function.

 However, the compiler is complaining:

  Error: returning where(stmt, "`id` = ?", id) escapes a 
 reference to local variable stmt

 But... it's not returning a ref. So why the complaint?

 I have to separate into 2 lines.

 I tried to make a simple example to show the problem, but looks 
 like it doesn't fail in that case.

 Any ideas?

 -Steve
Are you passing the -dip1000 switch to the compiler? I reproduced this with a toy version of your code, but the compile error goes away when I pass the -dip1000 switch to the compiler.
Nov 22 2019
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 11/22/19 10:46 PM, Meta wrote:
 
 Are you passing the -dip1000 switch to the compiler? I reproduced this 
 with a toy version of your code, but the compile error goes away when I 
 pass the -dip1000 switch to the compiler.
I am not. But I admit that I didn't have the return attribute at first. I added it to see if it helped (it didn't). Can you post the toy version? Might be reasonable for a bug report. I couldn't figure out a minimal case. -Steve
Nov 22 2019
parent reply Meta <jared771 gmail.com> writes:
On Saturday, 23 November 2019 at 04:20:33 UTC, Steven 
Schveighoffer wrote:
 On 11/22/19 10:46 PM, Meta wrote:
 
 Are you passing the -dip1000 switch to the compiler? I 
 reproduced this with a toy version of your code, but the 
 compile error goes away when I pass the -dip1000 switch to the 
 compiler.
I am not. But I admit that I didn't have the return attribute at first. I added it to see if it helped (it didn't). Can you post the toy version? Might be reasonable for a bug report. I couldn't figure out a minimal case. -Steve
It's just your code ( safe added for good measure): safe: struct SQLStatement { string s; } struct X { SQLStatement foo(int id) { auto stmt = SQLStatement("`foo`"); // table return stmt.where("`id` = ?", id); } } ref SQLStatement where(T)(return ref SQLStatement stmt, string clause, T val) { return stmt; } void main() { X x; x.foo(1); } This code fails to compile unless dip1000 is turned on.
Nov 24 2019
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 11/24/19 4:05 AM, Meta wrote:
 On Saturday, 23 November 2019 at 04:20:33 UTC, Steven Schveighoffer wrote:
 On 11/22/19 10:46 PM, Meta wrote:
 Are you passing the -dip1000 switch to the compiler? I reproduced 
 this with a toy version of your code, but the compile error goes away 
 when I pass the -dip1000 switch to the compiler.
I am not. But I admit that I didn't have the return attribute at first. I added it to see if it helped (it didn't). Can you post the toy version? Might be reasonable for a bug report. I couldn't figure out a minimal case. -Steve
It's just your code ( safe added for good measure): safe: struct SQLStatement {     string s; } struct X {    SQLStatement foo(int id)    {       auto stmt = SQLStatement("`foo`"); // table       return stmt.where("`id` = ?", id);    } } ref SQLStatement where(T)(return ref SQLStatement stmt, string clause, T val) {     return stmt; } void main() {     X x;     x.foo(1); } This code fails to compile unless dip1000 is turned on.
Oh my, I swear I put something similar into run.dlang.io and it compiled fine. I'll file a bug. -Steve
Nov 24 2019
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 11/24/19 11:28 AM, Steven Schveighoffer wrote:

 
 Oh my, I swear I put something similar into run.dlang.io and it compiled 
 fine.
 
 I'll file a bug.
The key here is that SQLStatement has a string in it. In my toy test, I didn't put anything (or I just put an int maybe?) Something about the pointer inside it makes a difference. According to run.dlang.io, it's been broken since 2.072.3 or so. Going to file now... -Steve
Nov 24 2019
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 11/22/2019 10:54 AM, Steven Schveighoffer wrote:
 I have code in my proprietary project that looks like this:
 
 struct X
 {
     ...
     SQLStatement foo()
     {
        auto stmt = SQLStatement("`foo`"); // table
        return stmt.where("`id` = ?", id);
     }
 }
 
 where is a function that adds a where clause with a given value to the SQL 
 statement. It takes an SQLStatement by ref, and returns that statement by ref.
 
 Signature looks like this:
 
 ref SQLStatement where(T)(return ref SQLStatement stmt, string clause, T val)
^^^ ^^^^^^^^^^
   Error: returning where(stmt, "`id` = ?", id) escapes a reference to local 
 variable stmt
 
 But... it's not returning a ref.
Yes it is. See the ^^^^
Nov 22 2019
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 11/22/19 11:26 PM, Walter Bright wrote:
 On 11/22/2019 10:54 AM, Steven Schveighoffer wrote:
 I have code in my proprietary project that looks like this:

 struct X
 {
     ...
     SQLStatement foo()
     {
        auto stmt = SQLStatement("`foo`"); // table
        return stmt.where("`id` = ?", id);
     }
 }

 where is a function that adds a where clause with a given value to the 
 SQL statement. It takes an SQLStatement by ref, and returns that 
 statement by ref.

 Signature looks like this:

 ref SQLStatement where(T)(return ref SQLStatement stmt, string clause, 
 T val)
  ^^^                       ^^^^^^^^^^
   Error: returning where(stmt, "`id` = ?", id) escapes a reference to 
 local variable stmt

 But... it's not returning a ref.
Yes it is. See the ^^^^
Yes, where is returning ref, but the complaint is not focused on that. It's saying returning the *result* of the where call is escaping the local. It's not. foo doesn't return ref. If I split it into: auto result = stmt.where("`id` = ?", id); return result; It works. This is what I'm expecting the compiler to do automatically. I'll note that I was using inferred return types previously, and I thought maybe that was the problem. But here I have specified the return type exactly. -Steve
Nov 23 2019
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 11/23/2019 4:10 AM, Steven Schveighoffer wrote:
 It works. This is what I'm expecting the compiler to do automatically.
Ok, but you're going to need to find a test case that can be put on bugzilla.
Nov 23 2019
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 11/23/19 6:32 PM, Walter Bright wrote:
 On 11/23/2019 4:10 AM, Steven Schveighoffer wrote:
 It works. This is what I'm expecting the compiler to do automatically.
Ok, but you're going to need to find a test case that can be put on bugzilla.
https://issues.dlang.org/show_bug.cgi?id=20416 -Steve
Nov 24 2019
parent Walter Bright <newshound2 digitalmars.com> writes:
On 11/24/2019 8:52 AM, Steven Schveighoffer wrote:
 https://issues.dlang.org/show_bug.cgi?id=20416
Thank you.
Nov 24 2019