Thread overview
[Issue 20868] DIP1000: scope delegate triggers error in unsafe code and it shouldn't
[Issue 20868] DIP1000: scope delegate is implicitly convertible to non-scope delegate
Jan 11
RazvanN
Jan 11
RazvanN
Jan 11
Dlang Bot
Jan 12
RazvanN
Jan 14
RazvanN
Jan 14
Bolpat
Jan 14
RazvanN
Jan 15
Dlang Bot
January 11
https://issues.dlang.org/show_bug.cgi?id=20868

RazvanN <razvan.nitu1305@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |razvan.nitu1305@gmail.com

--- Comment #1 from RazvanN <razvan.nitu1305@gmail.com> ---
The scope analysis is done only for @safe functions. Annotating scoped and non-scoped with @safe is going to trigger the error: 'scope variable `dg` assigned to non-scope parameter `dg` calling test.nonScoped'.

So the actual error is that `dgs ~= dg` triggers an error in unsafe code.

--
January 11
https://issues.dlang.org/show_bug.cgi?id=20868

RazvanN <razvan.nitu1305@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|DIP1000: scope delegate is  |DIP1000: scope delegate
                   |implicitly convertible to   |triggers error in unsafe
                   |non-scope delegate          |code and it shouldn't

--
January 11
https://issues.dlang.org/show_bug.cgi?id=20868

Dlang Bot <dlang-bot@dlang.rocks> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull

--- Comment #2 from Dlang Bot <dlang-bot@dlang.rocks> ---
@RazvanN7 created dlang/dmd pull request #12127 "Fix Issue 20868 - DIP1000: scope delegate triggers error in unsafe co…" fixing this issue:

- Fix Issue 20868 - DIP1000: scope delegate triggers error in unsafe code and it shouldn't

https://github.com/dlang/dmd/pull/12127

--
January 12
https://issues.dlang.org/show_bug.cgi?id=20868

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@digitalmars.com

--- Comment #3 from Walter Bright <bugzilla@digitalmars.com> ---
I'm not sure exactly what the problem is. Is it the

  // error

line, or the

  // not an error???

line?

  This should be a compile-time error.

Which line?

--
January 12
https://issues.dlang.org/show_bug.cgi?id=20868

--- Comment #4 from RazvanN <razvan.nitu1305@gmail.com> ---
Initially, it was `nonScoped(dg)` line that was reported as an error. However, the function is not annotated with `@safe` so I concluded that the actual problem is that the commented line (when uncommented) errors.

We need your clarification whether scope analysis should not apply in non-@safe contexts.

--
January 14
https://issues.dlang.org/show_bug.cgi?id=20868

--- Comment #5 from Walter Bright <bugzilla@digitalmars.com> ---
To be specific, when compiled with -dip1000:

  void scoped (scope void delegate() dg) {
    static void delegate()[] dgs;
    dgs ~= dg;  // Error: scope variable `dg` may not be copied into allocated
memory
  }

and there is no error without -dip1000.

The first thing to do is simplify:

  void scoped (scope void* p) {
    static void*[] px;
    px ~= p;
  }

which exhibits the same behavior. But let's try this:

  void scoped (scope void* p) {
    static void* px;
    px = p;
  }

which generates no error with or without -dip1000. Marking the function with @safe yields:

   Error: scope variable p is assigned to non-scope px

with or without -dip1000.

The examples must behave the same way. They don't, so which is right? The array examples are wrong.

--
January 14
https://issues.dlang.org/show_bug.cgi?id=20868

--- Comment #6 from RazvanN <razvan.nitu1305@gmail.com> ---
(In reply to Walter Bright from comment #5)
> To be specific, when compiled with -dip1000:
> 
>   void scoped (scope void delegate() dg) {
>     static void delegate()[] dgs;
>     dgs ~= dg;  // Error: scope variable `dg` may not be copied into
> allocated memory
>   }
> 
> and there is no error without -dip1000.
> 
> The first thing to do is simplify:
> 
>   void scoped (scope void* p) {
>     static void*[] px;
>     px ~= p;
>   }
> 
> which exhibits the same behavior. But let's try this:
> 
>   void scoped (scope void* p) {
>     static void* px;
>     px = p;
>   }
> 
> which generates no error with or without -dip1000. Marking the function with @safe yields:
> 
>    Error: scope variable p is assigned to non-scope px
> 
> with or without -dip1000.
> 
> The examples must behave the same way. They don't, so which is right? The array examples are wrong.

So you agree with the PR I made? It essentially makes the error at line `dgs ~= dg;` go away in -dip1000 context.

--
January 14
https://issues.dlang.org/show_bug.cgi?id=20868

Bolpat <qs.il.paperinik@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |qs.il.paperinik@gmail.com

--- Comment #7 from Bolpat <qs.il.paperinik@gmail.com> ---
(In reply to Walter Bright from comment #5)
> To be specific, when compiled with -dip1000:
> 
>   void scoped (scope void delegate() dg) {
>     static void delegate()[] dgs;
>     dgs ~= dg;  // Error: scope variable `dg` may not be copied into
> allocated memory
>   }

I only find the error message confusing. It should be an error: One cannot assign a scope object to a global state. Local static variables are not at global scope, but are a global state.

Allowing that would make `scope` absolutely useless as a guarantee and for optimizations. When the function is called with a lambda, its can be allocated on the stack, because the reference won't "survive" the call. With allowing assignment to local static variables, this is no longer the case.

--
January 14
https://issues.dlang.org/show_bug.cgi?id=20868

--- Comment #8 from RazvanN <razvan.nitu1305@gmail.com> ---
(In reply to Bolpat from comment #7)
> (In reply to Walter Bright from comment #5)
> > To be specific, when compiled with -dip1000:
> > 
> >   void scoped (scope void delegate() dg) {
> >     static void delegate()[] dgs;
> >     dgs ~= dg;  // Error: scope variable `dg` may not be copied into
> > allocated memory
> >   }
> 
> I only find the error message confusing. It should be an error: One cannot assign a scope object to a global state. Local static variables are not at global scope, but are a global state.
> 
> Allowing that would make `scope` absolutely useless as a guarantee and for optimizations. When the function is called with a lambda, its can be allocated on the stack, because the reference won't "survive" the call. With allowing assignment to local static variables, this is no longer the case.

The DIP and spec say that scope analysis should be done only when dip1000 is enabled and in @safe context. So this would make scope useless in non-@safe could, however, if the function is @safe it would still be an error.

--
January 15
https://issues.dlang.org/show_bug.cgi?id=20868

Dlang Bot <dlang-bot@dlang.rocks> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |FIXED

--- Comment #9 from Dlang Bot <dlang-bot@dlang.rocks> ---
dlang/dmd pull request #12127 "Fix Issue 20868 - DIP1000: scope delegate triggers error in unsafe co…" was merged into master:

- 0cd0d4ead58dcda199b65e056c5316138e425054 by RazvanN7:
  Fix Issue 20868 - DIP1000: scope delegate triggers error in unsafe code and
it shouldn't

https://github.com/dlang/dmd/pull/12127

--