Jump to page: 1 2
Thread overview
lifetime issue: Bug or not?
Nov 22, 2019
Jacob Carlborg
Nov 23, 2019
Meta
Nov 24, 2019
Meta
Nov 23, 2019
Walter Bright
Nov 23, 2019
Walter Bright
Nov 24, 2019
Walter Bright
November 22, 2019
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
November 22, 2019
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
November 22, 2019
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
November 23, 2019
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.
November 22, 2019
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

November 22, 2019
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 ^^^^
November 23, 2019
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
November 23, 2019
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.
November 24, 2019
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.


November 24, 2019
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
« First   ‹ Prev
1 2