What is holding back ZLS?

First of all, don’t get me wrong, I know this is a volunteer project. I know people are working on this everyday. But as I am using it, I don’t see any differences between versions. Autocompletions are still broken for me, types are still (unknown). Here are some questions:

  1. What is the current focus/direction of ZLS development?
  2. Zig is advertised as a simple language. Shouldn’t it lead to a simple language server as well?
  3. Can I have a really slow ZLS that does thing in some unga bunga way, but will give me the correct type inferences, autocompletions and stuff?

Thanks.

3 Likes

This might be of interest to you:

2 Likes

I’m not sure you are having the same problem I had when I first set up ZLS and zig.vim (neovim).

When saving there was a few, ever increasing delay, of few seconds (~5 sec). I tought it was ZLS being slow. But what fixed it was actually turning off automatic run of “zig fmt” on save. Now I have no problems.

I did not have other problems however.

I had this problem and it was caused by my antivirus (AVG). Turning it off solved it.

I’m not saying my ZLS is slow guys! I’m saying that I specifically want a slow ZLS, just give me the correct autocompletions everytime.

1 Like

I watched this and yes, it was fun. All I could remember are two things he mentioned: build system and comptime eval. I am working with a very simple pure zig project, so I don’t particularly sympathize with the build system thing.
But comptime evaluation, he mentioned “it’s slow” to run it repeatedly or something. I’m saying that, have anyone attempted this approach and built a ZLS that way then? I think something that works correctly is more valuable than something that works fast but wrong (or unhelpful, (unknown) etc etc). I have a feeling we are waiting for something clever, rather than making it work.

My exact thoughts, I would had contributed if I was not so dumb. There was some discussion about this on reddit a month ago or something.

Note that we tried “do a correct-low-effort-but-slow-thing using batch analysis results from existing compiler” with rust, and it didn’t work out. Originally, there was RLS (well, originally IntelliJ Rust actually, but that’s a different story…) which worked by asking the compiler to dump all into into JSON, and used that for precise analysis. It quickly reached “it’s usable-ish” stage, but then plateaued, and people become quite unhappy about IDE support (I think survey result from 2018 reflects that: Rust Survey 2018 Results | Rust Blog). Then rust-analyzer came along, which took a lot longer to reach the state where it mostly works, but then it leapfrogged RLS and there was much rejoicing:

https://github.com/rust-lang/rfcs/pulls?q=sort%3Areactions-%2B1-desc+

Ultimately, when it comes to IDE support, slow and steady wins the race: long term, correct architecture wins over “let’s whip something up quickly using what we have”. Given that Zig is not itself stable, I think it’s reasonable to wait here. The bricks underlying great IDE support are being laid — compiler now has server mode, there’s work underway to parallelize semantic analysis (and parallel analysis infrastructure uses the same underlying language properties the IDE would need On Modularity of Lexical Analysis).

Finally, I would say that ZLS already works much better than expected, given constraints. The only thing I personally miss right now is Support workspace symbol · Issue #778 · zigtools/zls · GitHub. Long term, I do very much look forward to fully-correct analysis based on compiler’s Sema, but that’s a looooong road to that. Rust has been doing incremental progress in this area for the past 8 years and is still not quite there :slight_smile:

EDIT: I should disclose that I was responsible for rust-analyzer side of the story, so my perspective is very biased.

13 Likes

Could you give an example of where autocomplete is broken for you or when it says the type is unknown? you might not have setup zls correctly or are using an old version. zls doesn’t always work because of comptime, but otherwise it works pretty good in my experience.

2 Likes

This is where I implemented an intrusive linked list.

Sample usage:

test {
    const Entry = struct {
        allocator: std.mem.Allocator,
        h: Node,
    };
    const h: Head(Entry, "h") = undefined;
    var it = h.iterator();
    while (it.next()) |n| {
        n.allocator;
        //     ^ (unknown)
    }
}

And I build zls from source, so don’t worry about version issue.

My zls config:

{
  "warn_style": true,
  "include_at_in_builtins": true,
  "dangerous_comptime_experiments_do_not_enable": true
}

Thanks for the reply. I don’t know how long since then, but nice hair cut :slight_smile:

See how Zig used LLVM at the start, gained traction, and now then decided to implement its own codegen. I do think that software is destined to change. I do think only by making something first can we explore what should be done correctly. I’m not so sure about sitting and crossing out options here. (crossing obviously wrong options is fine tho)

On rust-analyzer, I know Rust is fairly complex, given how much work has gone into making the borrow checker, the trait solver, etc and making the logic sound, correct, etc. But compared to Zig, that comes to my point 2 in the OP - on the home page it says Zig is simple. So I expect it should be different, no? If not then I don’t know what is the point of that simplicity.

The issue here is that there is a struct inside a struct that zls doesn’t seem to be able to handle. I’ll see if that is easy to fix in zls. If you have a function directly in the anonymous struct then zls is able to autocomplete that, even with the comptime type.

I have absolutely no idea what you are talking about. But yes, do contribute to zls if you can :slight_smile:

It’s a bit weird, I managed to get your example to work by rewriting it a bit so there seems to be a bug in zls specifically for your example.

it works if you do

h.iterator().next().?.h;

but not if you do

var it = h.iterator();
it.next().?.h;

Well, thats weird…

I also get “unknown” all the time. I came from Rust as well and will admit the analyzer capabilities are a bit of a night and day difference.

That’s going to be the case with a new language that’s not even at 1.0 yet though. So many changes are happening that tooling will always be tough to keep up to date and really refine. For pre 1.0 tooling that doesn’t have even close to the resources or community involvement Rust has, it is very good

Also Zig is a simpler language, but comptime and lazy evaluation will make type analysis substantially more difficult.

I’m not sure the IDE you’re working in, I’m using vscode. I’ve edited my extension so I can have proper syntax highlighting for unknown types based on case. I can share how if that would be helpful

1 Like

for reference, I used rust back when it was as old as zig is now and the rust tools actually worked worse than zls

1 Like

I do like this:
the data 0.11.0 is available
But only works with master zig dev version currently 0.12.0 dev

git clone https://github.com/zigtools/zls
cd zls
zig build -Doptimize=ReleaseSafe -Ddata_version="0.11.0"  

best if you have installed version 0.11.0 – ZIG

go get the 0.11 binary. on
https://github.com/zigtools/zls/releases/tag/0.11.0

After installing zig in your vscode
change path ZIG:ZIG PATH
ex. /home/…/.zig/zig

zig:ZLS:PATH
ex.: /home/…/.zls/zls After installing zig in your vscode

zig:ZLS:PATH
ex.: /home/sun/.zls/zls

3 Likes

Personally I am a dirty Visual Studio OG user and I really wish I could easily integrate ZLS with Visual Studio. I tried doing it myself but I got confused trying. Maybe one day.

Hi 0/, ZLS BDFL here. I imagine you’ve watched the talk Ryan linked above but here are my answers to some of the questions posed in this thread at this moment in time. :))

In short, our biggest enemy is time. We’re a team of 5 people who can only dedicate a small amount of time to ZLS per week as we have full-time jobs/university classes. It’s my hope that we can one day find a sustainable funding model to work more on ZLS (perhaps full-time!), and we’ve already begun paying one of our maintainers for his work (see zigtools - Open Collective), albeit significantly less than ideal.

Individual donators have been a huge help here, but it’s clear that companies will be our lifeline in this regard. My personal gameplan here is to wait for more companies using our Zig tooling to appear and hope they’ll fund us - this is already the case with Bun, TigerBeetle (hi matklad :P), and my employer Sourcegraph.

We’d be beyond excited if anyone would be interested in helping with development / donating (our GH Sponsors is most likely the best place for individuals) / finding sustainable, long-term sources of funding. Please feel free to reach out in the ZLS Discord Server found in our README. :))

Now to answer/respond to some questions/comments:

What is the current focus/direction of ZLS development?
There are a whole bunch of directions, which can be resumed as:

  • Performance
  • Stability
  • Accuracy

These are incredibly broad goals that will take a long time to address. I’ve tried to do some PM-esque stuff at the request of other ZLS maintainers so we can get a timeline/project board of some sort going for a finer view of short-term/long-tern goals but that hasn’t gone well so far. :sweat_smile:

Zig is advertised as a simple language. Shouldn’t it lead to a simple language server as well?

This is 100% true - most things in ZLS are rather simple and consistent because Zig is. Unfortunately, comptime and the build system exist, and though these are (relatively) simple and intuitive for a user, they’re an uphill battle for tooling.

Can I have a really slow ZLS that does thing in some unga bunga way, but will give me the correct type inferences, autocompletions and stuff?

I wish! ZLS is not designed to perform comptime resolution - it’s 100% AST based and performs no real type or semantic analysis (because of the aforementioned ease of the language). Everything we do is a guesstimate; if comptime didn’t exist, this guesstimation would make ZLS nearly perfectly accurate. I wrote ZLS this way in the first place because it was easier and I wanted a quick and easy way to help me navigate/complete Zig code for my own learning of the language.

Thankfully, we’re no longer at the “adding 100% correct comptime interpretation would require a massive amount of monthslong work” phase but rather at the “adding 100% correct comptime interpretation is actively requiring a massive amount of monthslong work” thanks to Techatrix’s excellent techatrix/stage2-sema (this isn’t really talked about publicly much as it’s far from ready and Techatrix can only allocate a few hours here and there per week into this branch). Note that this is 100% independent of the compiler, which has its own (pretty length) pros and cons list.

Given that Zig is not itself stable, I think it’s reasonable to wait here. The bricks underlying great IDE support are being laid — compiler now has server mode, there’s work underway to parallelize semantic analysis

Indeed; we’re exploring this along with our own avenues to land comptime support in a way that works for us. See Move Zir, InternPool, AstGen to `std.zig` by SuperAuguste · Pull Request #18127 · ziglang/zig · GitHub for the next steps on the compiler side of things.

I’m also working on mocking/implementing some changes to the build system for compiler server multiplexing which would incidentally resolve all our current problems with the build system. :))

Happy to discuss/answer anything else!

11 Likes