I would consider this an example of “hidden control flow”, which Zig doesn’t do. I understand the desire to have errors point to the relevant places in the master code, rather than the accidental spots in the generated code where it happens to be triggered.
But the thing is, that isn’t what’s happening. The error return trace and stack trace from errors is what the computer was actually executing when the error happened. That’s exactly what Zig should provide.
So @biosbob, let me give you some pointers on how you might solve the problem. Because yeah, there are good reasons to want errors to point somewhere more useful for your users.
I’m going to future-proof (for some values of future) this post, by explaining in terms of how things work on the master branch now, and how they will work in the 0.14 release. It isn’t that different in 0.13, and I’m sure you can fill in the small differences yourself.
Errors are printed by the panic handler, which is now std.debug.FormattedPanic. You’ll see that it receives a std.builtin.StackTrace
. This is your override point, you can replace this function with a custom one.
The stacktrace gets printed with std.debug.writeStackTrace, what you’ll need is a custom version of this. Your codegen will have to generate some kind of sourcemap, something you can @embedFile
to have available.
You’ll see logic in writeStackTrace
which takes the instruction stack and returns SourceLocation
objects, that gets acquired in std.debug.printSourceAtAddress, you can get the necessary data with std.debug.getSelfDebugInfo.
Clearly this is not a small undertaking. I think it illustrates, however, why Zig shouldn’t allow hidden control flow here. Once you write code to do this, it’s rock-solid: and it can’t be undermined by other code inducing the debug info to report false information about what happened.
So if this is important to your project, and I assume it is, you’ve got some work cut out for you. But all the pieces you need are there.