Jump to page: 1 2
Thread overview
[Issue 24208] [DIP1000] Nested function can escape scope parameter
[Issue 24208] [DIP1000] Nested function can pass scope pointer to non-scope parameter
Oct 29, 2023
Paul Backus
Oct 29, 2023
Paul Backus
Oct 29, 2023
Paul Backus
Oct 29, 2023
Paul Backus
Oct 29, 2023
Paul Backus
[Issue 24208] [DIP1000] Nested function can pass scope pointer to non-scope parameter
Oct 29, 2023
Paul Backus
[Issue 24208] [DIP1000] Scope pointer can escape via non-scope parameter of pure nested function
Oct 30, 2023
Paul Backus
Oct 30, 2023
Paul Backus
Oct 30, 2023
Paul Backus
Oct 30, 2023
Paul Backus
Oct 30, 2023
Dlang Bot
Oct 30, 2023
Dlang Bot
October 29, 2023
https://issues.dlang.org/show_bug.cgi?id=24208

Paul Backus <snarwin+bugzilla@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |accepts-invalid, safe

--
October 29, 2023
https://issues.dlang.org/show_bug.cgi?id=24208

--- Comment #1 from Paul Backus <snarwin+bugzilla@gmail.com> ---
Actually, it turns out the second function is not necessary:

---
void main() @safe
{
    int* escaped;

    void escape(int* p) @safe
    {
        escaped = p;
    }

    int n;
    escape(&n);
    assert(escaped == &n);
}
---

So, I guess the problem is either that the compiler is incorrectly inferring `p` as `return scope`, or it's *correctly* inferring `p` as `return scope` but failing to notice at the calls site that the "return value" has a longer lifetime than `n`.

If it's the second case, the error should be the same one produced by this program:

---
void main() @safe
{
    int* escaped;

    static void escape(ref int* ret, return scope int* p) @safe
    {
        ret = p;
    }

    int n;
    escape(escaped, &n);
    // Error: address of variable `n` assigned to `escaped`
    // with longer lifetime
    assert(escaped == &n);
}
---

--
October 29, 2023
https://issues.dlang.org/show_bug.cgi?id=24208

Paul Backus <snarwin+bugzilla@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|[DIP1000] Nested function   |[DIP1000] Nested function
                   |can pass scope pointer to   |can escape scope parameter
                   |non-scope parameter         |

--
October 29, 2023
https://issues.dlang.org/show_bug.cgi?id=24208

--- Comment #2 from Paul Backus <snarwin+bugzilla@gmail.com> ---
...or maybe the problem is that it's being incorrectly inferred as `scope` instead of `return scope`.

Another example:

---
void main() @safe
{
    int* escaped;

    void escape1(int* p) @safe
    {
        escaped = p;
    }

    void escape2(scope int* p) @safe
    {
        escaped = p;
    }

    void escape3(return scope int* p) @safe
    {
        escaped = p;
    }

    int n;
    escape1(&n); // no error
    escape2(&n); // error
    escape3(&n); // error
}
---

It's hard to tell what attributes the compiler is inferring here, but the observed behavior is consistent with the hypothesis that `scope int* p` is being inferred for `escape1`, and `return scope int* p` is being inferred for both `escape2` and `escape3`.

--
October 29, 2023
https://issues.dlang.org/show_bug.cgi?id=24208

--- Comment #3 from Paul Backus <snarwin+bugzilla@gmail.com> ---
Disregard previous example, I read the errors wrong. They occur in the function bodies, not at the call site. The parameter of `escape` is not allowed to escape at all if it is `scope`, even `return scope`.

--
October 29, 2023
https://issues.dlang.org/show_bug.cgi?id=24208

Paul Backus <snarwin+bugzilla@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|[DIP1000] Nested function   |[DIP1000] Nested function
                   |can escape scope parameter  |can pass scope pointer to
                   |                            |non-scope parameter

--
October 30, 2023
https://issues.dlang.org/show_bug.cgi?id=24208

Paul Backus <snarwin+bugzilla@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|[DIP1000] Nested function   |[DIP1000] Scope pointer can
                   |can pass scope pointer to   |escape via non-scope
                   |non-scope parameter         |parameter of pure nested
                   |                            |function

--- Comment #4 from Paul Backus <snarwin+bugzilla@gmail.com> ---
The bug is caused by an undocumented special-case language rule that allows scope pointers to be assigned to non-scope parameters of pure functions in some cases. This special case is implemented in the DMD frontend by the function TypeFunction.parameterStorageClass.

In comment #1's example, `escape` is inferred to be weakly pure. As a result, TypeFunction.parameterStorageClass allows the parameter `p` to accept a scope pointer as an argument, and the error that would normally be issued by checkParamArgumentEscape is suppressed.

--
October 30, 2023
https://issues.dlang.org/show_bug.cgi?id=24208

--- Comment #5 from Paul Backus <snarwin+bugzilla@gmail.com> ---
My mistake, this rule is documented, here:

https://dlang.org/spec/function.html#pure-scope-inference

--
October 30, 2023
https://issues.dlang.org/show_bug.cgi?id=24208

Paul Backus <snarwin+bugzilla@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           See Also|                            |https://issues.dlang.org/sh
                   |                            |ow_bug.cgi?id=24212

--
October 30, 2023
https://issues.dlang.org/show_bug.cgi?id=24208

Paul Backus <snarwin+bugzilla@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           See Also|                            |https://issues.dlang.org/sh
                   |                            |ow_bug.cgi?id=24213

--
« First   ‹ Prev
1 2