ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
33.67k stars 2.47k forks source link

`@src.file` file name collisions #20963

Closed leecannon closed 1 month ago

leecannon commented 1 month ago

Zig Version

0.14.0-dev.850+ddcb7b1c1

Steps to Reproduce and Observed Behavior

Files from different modules with the same relative path names from their respective root files have the same value for @src().file and therefore cannot be distinguished.

// build.zig
pub fn build(b: *std.Build) void {
    const exe = b.addExecutable(.{
        .name = "fff",
        .root_source_file = b.path("src/main.zig"),
        .target = b.standardTargetOptions(.{}),
        .optimize = b.standardOptimizeOption(.{}),
    });

    exe.root_module.addImport("dep1", b.createModule(.{
        .root_source_file = b.path("dep1/main.zig"),
    }));
    exe.root_module.addImport("dep2", b.createModule(.{
        .root_source_file = b.path("dep2/main.zig"),
    }));

    const run_cmd = b.addRunArtifact(exe);
    const run_step = b.step("run", "Run the app");
    run_step.dependOn(&run_cmd.step);
}

// src/main.zig
pub fn main() void {
    std.debug.print("{s}\n", .{@src().file});
    @import("dep1").printSrcFile();
    @import("dep2").printSrcFile();
}

// both dep1/main.zig and dep2/main are identical
pub fn printSrcFile() void {
    std.debug.print("{s}\n", .{@src().file});
}
$ zig build run
main.zig
main.zig
main.zig

Expected Behavior

In the context of a single compilation each file should have a unique @src().file.

rohlem commented 1 month ago

Related discussion in https://github.com/ziglang/zig/issues/19570 , somewhat related also https://github.com/ziglang/zig/issues/20864 and https://github.com/ziglang/zig/issues/20941. We could add an additional .module field to disambiguate, although iirc module names are currently local to the depender, and not unique across the build graph. Maybe the hash could work. I think for every module that cares about this (so on an opt-in basis), a userland solution (defining a "module name" constant to include in a userland Src struct) should be possible. I assume you have a use case for wanting to differentiate files across modules? Could you elaborate on your goal for compilation-unique @src values?

leecannon commented 1 month ago

One of the use cases of @src is for things like tracy.

With different files receiving the same path not only would tracy conflate traces from different source files it also has no way of locating the file from that path alone making it useless.

Although the zig compiler does not encounter an issue as it does not have imports of other modules with overlapping relative path names, its tracy bindings are susceptible to this issue:https://github.com/ziglang/zig/blob/f9f894200891c8af6ce3a3ad222cd0bf1ee15587/src/tracy.zig#L70

VisenDev commented 1 month ago

I believe this conflict was discussed on the discord. Especially in the case of projects like dvui that us @src for getting unique src locations. I believe andrew agreed to expand the capabilities of @src to include module information

Screenshot 2024-08-07 at 10 45 41 AM
mnemnion commented 1 month ago

I've made some comments in #20864 about this issue as well, which I'm linking to mostly because @andrewrk said the same thing there as in the screenshot.

To state what ohsnap needs in a goal-oriented way, it's the ability to use the output of @src() to find and open the source file. Any approach to that functionality works for me.

zkburke commented 1 month ago

I believe this conflict was discussed on the discord. Especially in the case of projects like dvui that us @src for getting unique src locations. I believe andrew agreed to expand the capabilities of @src to include module information

Screenshot 2024-08-07 at 10 45 41 AM

Just commenting here to say I was the one who initiated this discussion on the discord as I also have a use case for this. Any instrumentation library will need this (like tracy) and most immediate mode uis will use this as well. The usefulness of @src() is significantly neutered by allowing these name conflicts to occur. I'd be totally happy with a module field in SourceLocation as a minimum, but I don't want to repeat myself as I've mentioned this in the discord discussion. Just leaving my thoughts here for posterity.

andrewrk commented 1 month ago

Play with that a little and let me know what you think.

mnemnion commented 1 month ago

Will do, having some trouble with the build (not a request for help, working the Discord angle there), but I'll try it out as soon as I can.