On Saturday I had a long chat with Nick C about the Rust Language Server RFC, and about Racer and how it could all fit together. I wanted to write it up here, mainly to get things straight in my head.
After reading the RFC I thought I had a good idea of how it was going to work, but it turned out I was wrong in a number of places and the scope was larger than I had envisaged.
As I understand the plans correctly, the Rust language server (RLS) will be:
- A compiler - a replacement for the rustc command, for IDEs
- The IDE will use RLS rather than rustc to build software binaries
- RLS will include rustc internally and will also ship with all the rust standard libraries
- The IDE will coordinate actually building the software, and tell RLS what to build (in the same way cargo does for rustc); It could get information from cargo to do this
- A service API for answering low-level semantic queries
- e.g. queries like ‘tell me the fields+methods of <expression>’, ‘which traits are implemented by the type of this expression?’, ‘which call-sites refer to this function?’
- The IDE will then take these lower-level results and build functionality to perform suggestions, searches and refactorings
- A long running process (or a linked library, but long-running)
- RLS will manage an online internal database of semantic information, for a whole project (project is a potentually large collection of crates)
- A crates.io project (or at least that’s the intention). N.B. Building RLS will involve bootstrapping the whole compiler and building the rust libraries, so it will probably also be shipped as binaries in the same way rustc and the stdlibs are.
So in the RLS world the IDE performs both the build coordination, and generates code-completions, suggestions and performs code-transformations (e.g. refactorings). It uses the RLS as a sort of database to retrieve the information it needs to provide these suggestions and transformations. The composition of the RLS API is speculative at the moment.
(N.B. actually all of this is very early and speculative at the moment, so details will likely change in the coming weeks/months as stuff gets built)
Racer + Rustc
I personally hadn’t anticipated that RLS would be used to actually build the rust software. Before the proposal for RLS my intention for racer+rustc was:
client would use their current rustc + cargo build tools to build the project
- racer would link to the same version of rustc as the version being used to compile.
- This would allow racer+rustc to reuse the build artifacts from the built project (which are unstable and change between rustc versions)
rustc would provide a small library interface (which I’ll call ‘librustc’ here in a hand-wavy way)
librustc would have an interface for extracting analysis information at 3 levels of granularity and performance: * Whole crate analysis, taking many seconds to generate per crate * Whole crate ‘skeleton’ analysis, no function bodies, taking ~1 second to generate * Item analysis, taking ~100ms to generate
- The analysis information would be in the dxr ‘save-analysis’ style: - a set of expression spans with reference and type information (record oriented data) - not an ast or a graph
I was intending that the whole-crate analysis would be performed in batch mode on library crates (e.g. from crates.io), and records written to disk. The skeleton analysis would be performed periodically on the currently edited crate as the structure changed, and Item analysis would run continually as you type in response to completion suggestion requests.
The two approaches differ thus:
The focus of ‘librustc’ (hand-wavy-edition) is to export the analysis data. It doesn’t provide any indexing or querying
The focus of RLS is as a code database. The interface to the outside world is a query interface rather than the analysis data.
‘librustc’ (hand-wavy-edition) expects the client (racer in this case, or an ide) to
My main concern with the RLS approach is that it is top-down and big-bang. This is fine, but leaves racer in limbo for a bit. It will be a while before RLS can answer queries that
In an RLS world, racer’s role (as the ide interface for editors) changes a little: - It needs to coordinate builds - It performs completion queries by generating