This just came up in a discussion, and I've thought about this in the past, so it might have already come up. But often times, you have some code that you think will be @safe
, but it gets inferred to be @system
. However, you can't tell where the safety violation is, so you have this process where you make a clone of all the code, marking everything as @safe
, at all layers (even if they are in other projects) until you find the culprit.
As was pointed out in the discussion, the compiler knows where it decided to infer @system
, would it be possible to force it to tell you that?
An example:
void foo() {}
auto bar(int x) {
foo();
return x * 2;
}
void main() @safe {
auto a = bar(5);
}
The result is:
Error: `@safe` function `D main` cannot call `@system` function `bar`
Whereas it would be nice to see the error:
Error: `bar` was inferred `@system` because it calls `@system` function `foo`
Which should go all the way down to where the actual safety problem is. This is a simple example that's easy to diagnose, but often times you have a stack of template functions, and all you get is that the top layer function is @system
, instead of finding where it did the unexpected inference at the bottom of the stack (or you forgot to mark a @safe
non-inferred function).
This happens with stuff like format
or writeln
which is composed of dozens of layers of templates, and it's hard to find out which one is the one doing the unexpected inference. I have run across sometimes the inference giving up as well, which is a separate problem, but also useful to diagnose.
It would be nice to have a pragma (or maybe this can be a compiler diagnostic switch?) which shows the stack of inference that caused the safety error. Or maybe it should just always be shown? After all, it is an error, so no reason not to be fully descriptive.
-Steve