The error message for this code is verbose:
```
@safe @nogc pure nothrow:
void a(int* i) {
b((int x, int y, string s) {
return x + y + *(i + 1);
});
}
void b(scope int delegate(int x, int y, string s) @safe @nogc pure nothrow x) {}
```
The error is:
```
a.d(4): Error: function `a.b(scope int delegate(int x, int y, string s) pure nothrow @nogc @safe x)` is not callable using argument types `(int delegate(int x, int y, string s) pure nothrow @nogc @system)`
a.d(4): cannot pass argument `__lambda2` of type `int delegate(int x, int y, string s) pure nothrow @nogc @system` to parameter `scope int delegate(int x, int y, string s) pure nothrow @nogc @safe x`
a.d(3): Error: function `a.a` is `@nogc` yet allocates closures with the GC
a.d(4): a.a.__lambda2 closes over variable i at a.d(3)
```
The string representation of a delegate type can take up a lot of space. When dealing with a delegate with several parameters, it's easy to miss that the provided delegate is `@system` and was expected to be `@safe`.
At least, It would be nice if the diagnostic would point that out: "cannot pass argument `__lambda2` which is `@system` to parameter `x` which is `@safe`."
But ideally the error message would tell you *why* the delegate isn't @safe. An ideal error would be just:
```
a.d(5): Error: pointer arithmetic not allowed in @safe functions
```
which is what you get if you explicitly mark the delegate as @safe. Since there is only one overload of `b`, it seems like that the compiler could just make the delegate @safe automatically and issue errors on anything it finds that isn't @safe.
Also, the @nogc error is unrelated and goes away when fixing the @safe issue.
Comment #1 by robert.schadek — 2024-12-13T19:21:49Z