Introducing Rust Language Server, source release

@nrc and I have been hard at work on IDE support, turning the Rust Language Server demo we showed at RustConf into an actual project. Today, we’re making our first source pre-alpha release of the project.

We’re excited about what the RLS project will mean for Rust development in the future. The RLS aims at being a self-contained, full-featured application for IDE support. By being self-contained, and following a simple protocol, all the core IDE functionality will be available to any editor.

At least… that’s the theory. We still have a lot of work to get there. We need developers, testers, and people with expertise in various editors to help flesh out the support and make sure the experience feels good.

** The RLS is not yet ready for primetime **. This early release may eat your hard drive or frighten your neighbors. We recommend only using the RLS with code you are making regular backups of. If you are still interested, you can get started by following the guide.

Where we need help

First, we’re looking for people who want to write code and help flesh out the RLS. There are a growing list of issues to tackle as well as a number of FIXMEs in the code.

If you’re okay with living on the bleeding edge, we’d love to get testing feedback. Do features stop working in some cases? What were the steps that caused them to break? File an issue and let us know.

The RLS uses the Language Server Protocol, a json-rpc protocol backed by Microsoft and Red Hat. It’s a relatively young protocol. Currently, Eclipse and Visual Studio Code support this protocol, and it should be possible to add support to other editors. It just takes putting in the work.

What works

The current version supports the following features:

  • errors as you type
  • goto def
  • find all refs
  • renaming
  • types/docs/doc links on hover
  • types and docs from the standard library

What doesn’t work

Of course, not everything is roses. There are also some shortcomings:

  • Analysis can be slow. This is especially true for initial analysis, which has to work its way through all your dependencies.
  • Projects with dependencies that have custom build steps or compiler plugins aren’t supported out of the box. To support them you need to enable the “slow, but more accurate” mode by removing the “-Zno-trans” command to the compiler in build.rs.
  • Please use caution when using this. The RLS can make updates your code when doing tasks like rename/refactor. Always check that the RLS made edits that you expected. If not, file an issue so we can follow up.

Next steps

We’re currently working towards an Alpha release, which is geared towards a broader audience. To get there, we’ve tracking tasks to help us reach the Alpha.

If you have any questions you can ping nrc or jntrnr on irc.mozilla.org

67 Likes

I’d like to suggest that having “tls” as a substring of a 6-character project name might be misleading :slight_smile: There’s also https://github.com/ctz/rustls

Great work! I’ve been suitably warned, but nothing will stop me from testing this out :wink:

13 Likes

This is very exciting! I’m the maintainer of the equivalent thing for Scala (ensime.org) and I’m very pleased to see this coming to rust. One small piece of advice, because we learnt the hard way, don’t mutate source files in your server. Instead send diff files back to the editor. You get the advantage of allowing users to preview changes, but mostly it is a good precedent.

I’d love to see emacs support! Are you planning on supporting any other protocols, such as sexpressions over rpc or websockets? Ensime has multiple protocols, all generated automatically using scala’s equivalent of @derive

8 Likes

Might I suggest the “Rust Unified Tooling Helper, Linguistic Expert System Server”, or “ruthless”?

12 Likes

I’ll end up starting an emacs LS package soon, if someone doesn’t beat me to it.

7 Likes

Agreed! Mutating files on disk or within the server could cause issues with some editor integrations. With vim for example, it would be much better to apply the changes in the buffer as a single "change". This would then work with other vim functions like undo history. Otherwise, the user would constantly need to e! to get the latest contents from disk - yuck.

I'm really excited to see the RLS alpha approaching! I guess that means I should work on a YCM "completer" :slight_smile:.

5 Likes

The LS protocol responds to a request like refactor with a series of TextEdit objects, each of which says what span to update and what the new text should be. We’re not updating the source ourselves. That said, there’s nothing saying that we’re not sending some crazy TextEdit commands back to the server…

2 Likes

Yay! Glad to see https://github.com/nrc/rls-vfs :slight_smile:

Is there any plan about the eventual architecture of RLS and its desired relationship with the compiler, racer and rustfmt? Implementation overview describes the current situation, but it’s temporary, isn’t it?

Depends on how far out you want to look. Ideally, the RLS is integrated with cargo/rustc and is able to query for what the IDE needs interactively rather than having to wait for full build/typecheck cycles. This is sometimes called “pull-based” typechecking.

Once we have that, we can use the precise information directly, rather than using a heuristic tool like racer. That’s still a ways out, and it makes sense to use racer until the compiler is ready.

3 Likes

Hmm, on second read I’m not sure if you’re asking about wrapping tools more generally. Yeah, I imagine we might keep doing that for the foreseeable future, and then offer a single protocol for them.

Maybe change the repository name to rust-languageservice and keep RLS as short name.

Yeah, this is a very pre-alpha repo. As it matures, it’ll probably move to the nursery with a more official name.

1 Like

:+1:

4 Likes

So excited!! Didn’t see autocomplete listed?

Edit: nevermind, I should’ve read the previous comments.

rust-lang-service seems like a nice enough compromise.

5 Likes

Currently the output of save-analysis contains only the code for the current configuration, so a “single pass” is not enough to guarantee a complete symbol name refactor. One solution could be doing multiple passes using -C extra-filename and merge the multiple analysis files. This maybe can work for the test cfg (which is the most common case), but not for more complex/impredictable cfgs. [Even worse for "platform cfg" which would not even compile…so no analysis and no refactoring] I wonder how you plan to solve this problem.

Another problem is that a binary program needs a full build of the needed libraries to compile, cause it needs the metadata. So a project with a bin and a lib, would require rebuilding the lib each time to get the analysis for the bin, which would be very slow. Maybe the compiler should gain to ability to output only the metadata (.rmeta file ??) instead of a full .rlib ?

Awesome, nice to see the work on the LS coming along, this will be a great boon to Rust community! :smiley:

Note: Eclipse Ché supports LSP, but not regular Eclipse. Despite the similar name these are very two totally different IDEs, Eclipse Ché is a cloud based IDE, and otherwise Eclipse is just the regular (desktop) Eclipse.

There are plans to support LSP in regular Eclipse tooo, work is underway.

1 Like

Hi - project lead for Eclipse Che. This is a great step forward. A couple of items for you to think about:

  1. Eclipse Che currently provides LSP support, but I believe that Eclipse and Orion (a web editor) are thinking about their path forward. All are Eclipse projects, but different platforms with Che being a distributed workspace server and cloud IDE. Che has been shipping support for a couple months in the 5.0 milestone train. We have another generational advance planned and this is the epic for that. https://github.com/eclipse/che/issues/2109

  2. With that, Che has provided a packaging approach that we call agents which will package different language servers for dynamic deployment in a distributed workspace. We would very much like it if you could open a tracking GitHub ticket so that your language server can be packaged as an agent and deployable within workspaces. It’s not a lot of work, just a ZIP packaging and some bash scripts that help unpack it and start the server, registering it with a browser IDE. We would then make sure that this package was associated with the Rust workspace stack and Rust file types. We have been seeking more language servers for testing, and this is perfect. Zend has been doing a lot of work related to having PHP support in the same way - you can see their tracking epic here. https://github.com/eclipse/che/issues/2590. They are going pretty far beyond the basics.

  3. And (cough cough) to be fair, it was Microsoft, RedHat and my company, Codenvy, as the initial companies that pushed the language protocol out the door :). Codenvy is a supporter of Che and we felt this was essential to allow languages to be used in a distributed setting, and we wanted interoperability with VS Code and other IDEs.

5 Likes

I think the guys at Sourcegraph have started on an emacs language server already. You may want to ask them about it.

1 Like

Super exciting! I might explore adding Emacs integration (the ‘kitchen sink’ editor :slight_smile:).

Should I be worried about JSON-RPC protocols running locally? There was a security update for Guile recently due to offering dev tools listening on localhost over HTTP. I suppose at this point, the only change a malicious user could make are the refactorings.

2 Likes