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.
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:
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.