www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 24003] New: return/scope inference does not end up in type to

https://issues.dlang.org/show_bug.cgi?id=24003

          Issue ID: 24003
           Summary: return/scope inference does not end up in type to some
                    degree
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: qs.il.paperinik gmail.com

When function attributes are inferred, they end up in the type:
```d
auto f() {}
static assert(is(typeof(&f) == void function()  safe nothrow  nogc pure));
```

However, when parameters’ `scope` and `return` attributes are inferred, they
are not displayed in error messages or `pragma(msg)`.

They might not be displayed, but could still (silently) be part of the type;
but in a Schrödinger fashion, they are and they are not:

```d
auto f(int[] xs)  safe
{
    static int ctr;
    ctr++; // force impure
    return xs;
}

void tplTypeInfer(F)(ref F fp1, ref F fp2)
{
    int[3] xs;
    fp1(xs);
    fp2(xs);
}

//void nonTpl(ref int[] function(int[] xs) nothrow  nogc  safe fp)  safe
//{
//    //int[3] xs;
//    //fp(xs);
//}

void main()  safe
{
    int[3] xs;
    f(xs);   // good: `xs` binds to parameter inferred `return scope`.

    static assert(typeof(&f).stringof == 
                      "int[] function(int[] xs) nothrow  nogc  safe");
    alias F1 = int[] function(int[] xs) nothrow  nogc  safe;
    alias F2 = typeof(&f);
    static assert(is(F1 == F2)); // PASSES!
    F1 fp1 = &f; // This and …
    F2 fp2 = &f; // … this should behave the same, right?
    fp1(xs); // error: reference to local variable `xs` assigned to non-scope
parameter `xs`
    fp2(xs); // good (apparently, the parameter is scope here)

    tplTypeInfer(fp1, fp2);    // good/error depending on if nonTpl is
commented-in 
    tplTypeInfer(fp2, fp1);    // good/error (same)
    tplTypeInfer!F1(fp1, fp2); // good/error (same)
    tplTypeInfer!F1(fp2, fp1); // good/error (same)
    tplTypeInfer!F2(fp1, fp2); // good/error (same)
    tplTypeInfer!F2(fp2, fp1); // good/error (same)
}
```
It seems that if you *use* the function pointer, it remembers somehow that the
parameter is inferred scope.
Also, there’s some Schrödinger action going on with template type inference.

--
Jun 20 2023