On Monday, 15 January 2024 at 18:16:44 UTC, Bastiaan Veelo wrote:
Hey people, I can use some help understanding why the last line produces a compile error.

```d
import std.stdio;

struct S
{
    static void foo(alias len)()
    {
        writeln(len);
    }
}

void S_foo(alias len)()
{
    writeln(len);
}

void main()
{

    const five = 5;
    S_foo!five; // Fine
    S.foo!five; // Error
}
```

The error is
```
onlineapp.d(7): Error: `static` function `onlineapp.main.foo!(5).foo` cannot access variable `five` in frame of function `D main`
onlineapp.d(19):        `five` declared here
onlineapp.d(21): Error: template instance `onlineapp.main.foo!(5)` error instantiating
```

It seems to me this should just work.

It seems that since you write `static` to the member function signature, the compiler thinks the function shouldn't be allowed to have a hidden parameter that is needed to access `const five` from `foo`.

At a first glance it seems this should be allowed, since `static` means "no access to the type or function enclosing the member function", which wouldn't appear to say anything about the hidden frame pointer to the `alias` context as opposed to the enclosing struct.

But thinking about it, function templates are a shorthand for epnymous templates. I think the code get's rewritten to:

```D
struct S
{
    template foo(alias len)
    {
        static void foo()
        {
            writeln(len);
        }
    }
}
```

. As you can see, in the rewritten form you actually are accessing the outer scope, which is exactly what `static` is supposed to prevent.

On the other hand, if you move the template out of the struct you say this still works, even when it shouldn't according to my theory. I'm of the opinion that something in the compiler needs fixing here, but I'm not quite sure what.

Reply via email to