I switched to the language server because I felt running the actual compiler will in the long term always work better than writing your own parser. I was on the Jetbrains student discount, so I made a small recurring contribution to the rust language server project.
I think in retrospect that was the correct decision. The language server team has done great work, and they support things impractical to do with just parsing like autocompleting functions defined by macros.
No, it won't. A compiler and an IDE code analyzer have completely different non-intersecting goals.
As an example, consider error recovery. Where a compiler can just fail with an error, in an IDE you need to continue to provide full correct syntax highlighting, display all other potential errors and warnings, continue providing code analysis (including suggestions on how to fix the error) etc.
> The language server team has done great work, and they support things impractical to do with just parsing like autocompleting functions defined by macros.
None of these are provided by the language server team. These are provided by whoever wrote the code to analyze your stuff and provide data to the language server.
That's the conventional wisdom. The rust team's theory was that they could make it work. They did.
> As an example, consider error recovery. Where a compiler can just fail with an error, in an IDE you need to continue to provide full correct syntax highlighting, display all other potential errors and warnings, continue providing code analysis (including suggestions on how to fix the error) etc.
Possibly the Rust compiler's unusual prioritization of friendly error messages with helpful suggestions meant this wasn't as big a difference as you thought?
> None of these are provided by the language server team. These are provided by whoever wrote the code to analyze your stuff and provide data to the language server.
That's how it works for many languages: the language server implementation is a thin wrapper around an existing tool. That's not the case for rust. I've watched the work the Rust language server team did on their language server implementation and the compiler. It was impressive.
They didn't. Does the rust compiler support continuous analysis required by an IDE?
> That's not the case for rust.
Funny. Rust analyzer blog would have us believe that they have their own parser and analyzer.
From rust-analyzer's main contributor [1]
=== start quote ===
The essential complexity for a server is pretty high. It is known that compilers are complicated, and a language server is a compiler and then some.
First, like a compiler, a language server needs to fully understand the language, it needs to be able to distinguish between valid and invalid programs. However, while for invalid programs a batch compiler is allowed to emit an error message and exit promptly, a language server must analyze any invalid program as best as it can. Working with incomplete and invalid programs is the first complication of a language server in comparison to a compiler.
Second, while a batch compiler is a pure function which transforms source text into machine code, a language server has to work with a code base which is constantly being modified by the user. It is a compiler with a time dimension, and evolution of state over time is one of the hardest problems in programming.
Third, a batch compiler is optimized for maximum throughput, while a language server aims to minimize latency (while not completely forgoing throughput). Adding a latency requirement doesn’t mean that you need to optimize harder. Rather, it means that you generally need to turn the architecture on its head to have an acceptable latency at all.
=== end quote ===
Rust analyzer uses a custom parser [2]
=== start quote ===
a hand-written recursive descent parser, which produces a sequence of events like "start node X", "finish node Y". It works similarly to kotlin's parser, which is a good source of inspiration for dealing with syntax errors and incomplete input. Original libsyntax parser is what we use for the definition of the Rust language. TreeSink and TokenSource traits bridge the tree-agnostic parser from grammar with rowan trees.
=== end quote ===
[1] https://matklad.github.io/2022/04/25/why-lsp.html
[2] https://github.com/rust-lang/rust-analyzer/blob/master/docs/...
It is. Error recovery is one of the biggest issues precisely for the reason you mentioned :)