Currently, @src() returns source it's own location, even in inline functions:
const std = @import("std");
inline
fn f(a: std.builtin.SourceLocation) void {
const b = @src();
inline for (.{ a, b }, .{ "a", "b" }) |location, name| {
std.debug.print("{s} = {s}:{}:{}\n", .{
name,
location.file,
location.line,
location.column,
});
}
}
pub fn main() void {
f(@src());
}
a = main.zig:16:7
b = main.zig:4:15
Given that inline functions are inlined semantically, it is theoretically possible to also provide SourceLocation of the call-site. There are several ways to handle this:
- Just change
@src() to always be caller's location in an inline function
- Provide
@callerSrc() which is a syntax error if called outside of inline fn
- Add
caller: ?*SourceLocation field to std.builtin.SourceLocation which is non-null iff @src() is inside a function. This allows for having several levels of ancestral @src() if an inline function calls another inline function.
- Maybe something else?
If implemented, this feature could enable several patterns. For example, there's a Rust GUI framework that uses equivalent feature to implement Flutter-like memorization: https://github.com/anp/moxie/blob/4f71b6f28340b2db263f07d0883394fa0b233de0/topo/src/lib.rs#L140-L192
Specific use-case I am interested in is this:
pub inline fn assert(condition: bool) {
const src = @callerSrc();
if (!condition) {
std.debug.panic("assertion failure: {s}:{}:{}", .{src.file, src.line, src.column})
}
}
That is, I want to write an assert function which prints the location of the failure even if the code is compiled with Release, and all debug info is stripped.
Currently,
@src()returns source it's own location, even in inline functions:Given that
inlinefunctions are inlined semantically, it is theoretically possible to also provideSourceLocationof the call-site. There are several ways to handle this:@src()to always be caller's location in an inline function@callerSrc()which is a syntax error if called outside ofinline fncaller: ?*SourceLocationfield tostd.builtin.SourceLocationwhich is non-null iff@src()is inside a function. This allows for having several levels of ancestral@src()if an inline function calls another inline function.If implemented, this feature could enable several patterns. For example, there's a Rust GUI framework that uses equivalent feature to implement Flutter-like memorization: https://github.com/anp/moxie/blob/4f71b6f28340b2db263f07d0883394fa0b233de0/topo/src/lib.rs#L140-L192
Specific use-case I am interested in is this:
That is, I want to write an
assertfunction which prints the location of the failure even if the code is compiled with Release, and all debug info is stripped.