zls icon indicating copy to clipboard operation
zls copied to clipboard

more accurately model how build system modules work

Open Techatrix opened this issue 1 month ago • 3 comments

ZLS had an inaccurate view of how modules work in the build system. It would previously merge every module in the entire build graph into one single module which can easily lead to incorrect results in any non trivial project that contains multiple modules. This PR will keep track of each individual module so that analysis can differentiate between them just like how the compiler does it.

Some examples of what has been improved:

  • @import("root") now actually figures out in which module a given file is in.
  • auto complete for @import will only show the modules that have been directly added to the module that the current file belongs to
  • @import("some_name") will resolve the correct module if there are multiple modules that have imported different modules with "some_name" as their name.

One issue this PR doesn't fully address is when there are multiple modules with the same root source file that have conflicting definitions. This is only achievable using multiple compilation units because Zig fortunately disallows sharing a root source file within a single compilation unit.

Related PR #2308

Techatrix avatar Nov 18 '25 15:11 Techatrix

@import("root") now actually figures out in which module a given file is in.

fyi - it seems that can't really be relied upon

https://gist.github.com/dotcarmen/7f186613f1f839427a839c33306af9dd <- the output is:

hello, world!
exe says hello

what happens when a module is imported by multiple roots? i think it's best to not resolve @import("root") to anything to avoid any footguns

dotcarmen avatar Nov 25 '25 23:11 dotcarmen

fyi - it seems that can't really be relied upon

https://gist.github.com/dotcarmen/7f186613f1f839427a839c33306af9dd <- the output is:

I turns out that I have misunderstood the semantic of @import("root") as I assumed it would be the root source file a given file is inside but it is root source file of the compilation unit(s) a given file is in. I have updated the PR to handle this which should fix the issue in the example you provided.

what happens when a module is imported by multiple roots?

Resolve it to all of them. ZLS has something called "either types" that can be used to represent a type that can be one of a given set of types but it's unknown which one it will be.

So const root = @import("root") would be internally represented as:

const root = switch (unknown) {
    0 => @import("main.zig"),
    1 => @import("main2.zig"),
};

If main.zig and main2.zig if both root modules that import the file we are in.

complete example: https://gist.github.com/Techatrix/80b625e5965ca6177ff4360713ffded3

Techatrix avatar Dec 05 '25 21:12 Techatrix

i've been running this build pretty successfully, however, as of 0.16.0-dev.1484+d0ba6642b, i'm getting an error about LazyPath.getPath being called during the configure phase

this only occurred after i added b.addTranslateC step

dotcarmen avatar Dec 09 '25 14:12 dotcarmen