Thread overview
How to replicate an Error: scope variable `old` assigned to `ref` variable `ctx` with longer lifetime?
4 days ago
matheus
4 days ago
Dennis
3 days ago
matheus
3 days ago
Dennis
3 days ago
matheus
3 days ago
Dennis
4 days ago
I saw a post (https://forum.dlang.org/post/aklmfkzqpsraprjfxsjh@forum.dlang.org) by Dennis where he gives an example:

>Finally, mechanical scope checking has false positives:
>```D
>void f(ref scope S ctx)
>{
>    const old = ctx;
>    g(ctx);
>    ctx = old; // Error: scope variable `old` assigned to `ref` variable `ctx` with longer lifetime
>
>}
>```

So I'd like to try it out, so I wrote the snippet below:

@safe

import std;

struct S{}

void f(ref scope S ctx) {
    const old = ctx;
    g(ctx);
    ctx = old;
}

void g(ref scope S ctx) {
    S a;
    ctx = a;
}

void main(){
   S i;
   f(i);
}

But no errors. I tried Class too and no errors again.

Could someone please show me how can a replicate?

Thanks,

Matheus.
4 days ago

On Monday, 12 May 2025 at 21:46:04 UTC, matheus wrote:

>

I saw a post (https://forum.dlang.org/post/aklmfkzqpsraprjfxsjh@forum.dlang.org) by Dennis where he gives an example:

So I'd like to try it out, so I wrote the snippet below:

@safe

import std;

struct S{}

Make sure S contains at least one pointer, and compile with -preview=dip1000

3 days ago
On Monday, 12 May 2025 at 22:57:22 UTC, Dennis wrote:
> On Monday, 12 May 2025 at 21:46:04 UTC, matheus wrote:
>> I saw a post (https://forum.dlang.org/post/aklmfkzqpsraprjfxsjh@forum.dlang.org) by Dennis where he gives an example:
>>
>> So I'd like to try it out, so I wrote the snippet below:
>>
>> @safe
>>
>> import std;
>>
>> struct S{}
>
> Make sure S contains at least one pointer, and compile with -preview=dip1000

First thanks for replying!

Unfortunately adding the pointer gives me another error:

import std;

struct S{ int *p; }

void f(ref scope S ctx) {
    const old = ctx;
    g(ctx);
    ctx = old;
}

void g(ref scope S ctx) {
    S a;
    ctx = a;
}

void main(){
   S i;
   f(i);
}

onlineapp.d(8): Error: cannot implicitly convert expression `old` of type `const(S)` to `S`

If I replace:

 ctx = old;

To:

 ctx = cast(S)old;

It compiles without any error.

https://run.dlang.io/?compiler=dmd&args=-preview%3Ddip1000&source=import%20std;%0A%0Astruct%20S%7B%20int%20*p;%20%7D%0A%0Avoid%20f(ref%20scope%20S%20ctx)%20%7B%0A%20%20%20%20const%20old%20%3D%20ctx;%0A%20%20%20%20g(ctx);%0A%20%20%20%20ctx%20%3D%20cast(S)old;%0A%7D%0A%0Avoid%20g(ref%20scope%20S%20ctx)%20%7B%0A%20%20%20%20S%20a;%0A%20%20%20%20ctx%20%3D%20a;%0A%7D%0A%0Avoid%20main()%7B%0A%20%20%20S%20i;%0A%20%20%20f(i);%0A%7D

Matheus.
3 days ago

On Tuesday, 13 May 2025 at 11:55:21 UTC, matheus wrote:

>

Unfortunately adding the pointer gives me another error:

I added @safe: and replaced const with auto because casting away const isn't safe. This should do it:

// compile with -preview=dip1000
import std;

@safe:

struct S { int* p; }

void f(ref scope S ctx) {
    auto old = ctx;
    g(ctx);
    ctx = old;
}

void g(ref scope S ctx) {
    S a;
    ctx = a;
}

void main() {
   S i;
   f(i);
}
3 days ago
On Tuesday, 13 May 2025 at 12:08:09 UTC, Dennis wrote:
> On Tuesday, 13 May 2025 at 11:55:21 UTC, matheus wrote:
>> Unfortunately adding the pointer gives me another error:
>
> I added @safe: and replaced `const` with `auto` because casting away const isn't safe. This should do it:
>
> ...

Indeed it worked, but I scratched my head because I wrote almost the same code to test (with auto) and it wouldn't give me an error, and if you see my first post I wrote:

"@safe" without ":" at the beginning. While adding ":" finally did it:

onlineapp.d(10): Error: scope variable `old` assigned to `ref` variable `ctx` with longer lifetime

Maybe the compiler it should give an warning in that @safe without ":" when marking all the file?

Anyway thanks for your help,

Matheus.
3 days ago

On Tuesday, 13 May 2025 at 12:22:44 UTC, matheus wrote:

>

Maybe the compiler it should give an warning in that @safe without ":" when marking all the file?

@safe, like any attribute, can be applied in multiple ways:

// apply to next declaration
attr declaration;

// apply to a scope of declarations
attr { declaration; declaration; }

// apply to all subsequent declarations in this scope
attr:
declaration;
declaration;

Sometimes an error is given for clearly 'useless' attributes, like final int x;, but in general determining whether an attribute was written intentionally is complex. Variables can't be pure, but:

pure T var;

pure still has an effect when T is a function/delegate type. And while T could still be clearly resolved in this simple case, just wait until templates get involved!

>

Anyway thanks for your help,

No problem