Comment #0 by bradley.chatha — 2020-12-20T15:11:07Z
Relevant forum post: https://forum.dlang.org/thread/[email protected]
Marked as Major as I believe this is a large error in D's safety and correctness.
The following code:
```
// https://godbolt.org/z/j8f3x5
struct C
{
int a;
}
alias Func = void function(ref string);
void doShizz(alias _)(ref string a)
{
a = "Hello!";
}
static void staticShizz(alias _)(ref string a)
{
a = "Hello!";
}
void main()
{
import std;
string s;
// Alias to member field causes the compiler to insert a context pointer.
// doShizz!(C.a)(s); Error: need this for doShizz of type pure nothrow @nogc @safe void(ref string a)
// However, it's still treated like a normal function, so this works...
Func f = &doShizz!(C.a);
f(s); // Uh Oh: Compiles.
writefln("ptr: %X | length: %s", s.ptr, s.length); // ptr: 0 | length: 0
// But if we mark it static...
staticShizz!(C.a)(s);
writefln("ptr: %X | length: %s", s.ptr, s.length); // ptr: [omitted] | length: 6
}
```
Shows that even though `doShizz` becomes implicitly nested inside of `struct C`, meaning that it has a context pointer inserted into its parameters, the compiler is allowing this "function" to be assignable to a `function` variable.
And as you can see, it produces unexpected behaviour when called.
Unless I'm missing something even more obscure about this behavior, the compiler should not be allowing the `Func f = &doShizz` assignment.
Comment #1 by robert.schadek — 2024-12-13T19:13:33Z