Thread overview | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
November 22, 2019 lifetime issue: Bug or not? | ||||
---|---|---|---|---|
| ||||
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 Re: lifetime issue: Bug or not? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 Re: lifetime issue: Bug or not? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | 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 Re: lifetime issue: Bug or not? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 Re: lifetime issue: Bug or not? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | 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 Re: lifetime issue: Bug or not? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 Re: lifetime issue: Bug or not? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | 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 Re: lifetime issue: Bug or not? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 Re: lifetime issue: Bug or not? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 Re: lifetime issue: Bug or not? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | 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
|
Copyright © 1999-2021 by the D Language Foundation