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:

1 Like

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.

9 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

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.