Skip to content

Consider if @src() in an inline function should refer to the caller's location #21906

Open
@matklad

Description

@matklad

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    proposalThis issue suggests modifications. If it also has the "accepted" label then it is planned.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions