Hacker News new | past | comments | ask | show | jobs | submit login
Rust-Analyzer Architecture (github.com/rust-analyzer)
287 points by ibraheemdev on Feb 4, 2021 | hide | past | favorite | 65 comments



Big fan of rust-analyzer and have been using it since early alpha. Much better than RLS and approaching all the features in the Rust plugin for Clion/JetBrains. Got me off Clion during WFH because of the massive memory/CPU requirements of using a big IDE on a laptop when developing.

Rust being a terse language with generics and macros, sometimes figuring out what type an object is is hard and can easily get lost. Rust analyzer + vscode instantly gives context visually in all my code and even names types better than when the compiler errors at you when you get it wrong. This is especially true when dealing with a lot of async rust and you need to know the exact fully declared type of an object so you can fully decl it's type for a pin/box to pass around. Game changer. Being able to use to jump to definition is a huge win. I can walk code so much easier now and understand issues without a lot of mental energy or digging. It also updates in realtime as I code.

Big productivity boost I know for a lot of devs on Fuchsia. It would take me at least twice as long to get up with a new crate and be productive with it. The same is true as my own code base grows and I can't keep it all in my memory and remember. Impossible to stay as productive as code grows in rust without something like this anymore.

Also a huge win for the fact that it works remotely with vscode's remote features so I can have my code + rust-analyzer on my big linux machine remotely but still edit that code and get the context locally on my dinky/slower/older macbook.

My only wish is that it eventually gains some of the deeper refactoring features in vscode you can still get in Rust + Clion/JetBrains. Almost there.


Still waiting on my favorite jetbrains feature—show type of selected expression. Probably the single most used IDE feature in my toolbox when I used scala.


It looks like this is blocked upstream by the language server protocol not passing the current selection for hover requests [0].

0: https://github.com/microsoft/language-server-protocol/issues...


FWIW, this should be relatively easy to implement. Looking at all the pieces which implement https://github.com/rust-analyzer/rust-analyzer/blob/master/d... should given enough knowledge to do this.


At least in Emacs, it shows the type as a tooltip if I hover over the closing paren of a function call.


Works in VSCode too, not sure what specifically their problem is.


With inline hints you can get something somewhat similar, although they can get very annoying with complex types. But extremely useful in long method chains.


> It also updates in realtime as I code.

If anyone knows how to turn this off in vim/ale, I'd appreciate it.


Take a look at neovim 0.5 beta [0]. It has native support for LSP [1], and it's on par with other editors.

[0]: https://github.com/neovim/neovim [1]: https://neovim.io/doc/user/lsp.html


If you can please let me know how to turn this off in neovim with its native LSP support, I'd appreciate it.


It is unclear what exactly you wish to turn off, but you might be looking for this option: https://rust-analyzer.github.io/manual.html#rust-analyzer.di...


There should be an option to turn on cargo check only on file save


I use cargo as my linter now, but I'd like to use analyzer on file save


For those who don't know, rust-analyzer is an implementation of the Language Server Protocol for the Rust programming language, written in Rust. It assists you while you program, for example finding usages of a piece of code or going to the definition of a function. Basically a Rust IDE that you can plug into any text editor (in theory).


It is also worth noting that rust-analyzer is the successor to RLS. If anyone is still using the RLS (most editor plugins can be configured to use either), they should switch to rust-analyzer. It is much much better in almost every possible way, and soon to be made the "official" rust LSP [0].

0: https://github.com/rust-analyzer/rust-analyzer/issues/4224


I got convinced to use rust-analyzer instead of RLS by a comment like yours on hacker news ! I can't thank you enough ! It's almost like Rust became a different -much pleasant- language after that !


How is the Emacs support for this LSP implementation? Does it actually work comparably well to VS Code, or is it going to be like trying to use Emacs as a Java IDE back in the day: fighting your tooling constantly and getting little help from it.


The emacs support is great. I use emacs 'racer' and 'lsp' packages full time for development.

There are two popular emacs packages for rust-analyzer: lsp[0] and eglot[1]. lsp (language server protocol) package is the default for racer. Eglot has far more features and is correspondingly resource hungry.

Detailed type information has a super helpful impact on my ability to review Rust code in general. I find reviewing rust code much more productive when I can see what owns a variable, how long it lives, and how it's being used (immutable vs mutable). So yea, lsp or eglot. Super helpful.

[0] https://emacs-lsp.github.io/lsp-mode/ [1] https://github.com/joaotavora/eglot


I use rust-analyzer with Emacs every day for work. There was a small amount of initial setup time (one or two bugs that had to be fixed with line or two in the init file), and since then, I haven't had to do anything; it's just worked fine.


I use it in Emacs every day since a few years. It mainly works, but I still haven't figured out the best way to set the right feature flag combinations if I work in a crate that uses them a lot. In these cases, if some code requires a feature to be enabled, analyzer does nothing because it compiles with the feature disabled.

It's not bothering me that much that I'd find a solution, because I don't need the help of analyzer in crates that I maintain anymore...


Anecdote: it worked fine for me in spacemacs. I switched from spacemacs to VSCode because the latter's vi emulation was better, not because r-a didn't work well.


I use it with Spacemacs for 6+ months now and it's only getting better with time.

It's 99% reliable.


If you want to use the rust-analyzer LSP, you might want to switch to the rust-analyzer VSCode extension instead of the Rust one. There is a reason the "official" one doesn't use it yet and having a flaky autocomplete is the worst.


With dark mode it's hard to read the Bird's Eye View diagram: https://imgur.com/a/pJwZP9v

I guess a consequence of dark mode is you should not use transparency in your diagrams if you have black lines.


"Open image in a new tab" to the rescue! The extension I use (Dark Reader) didn't force dark mode for images, which means I can see the labels just fine in these cases.


It shouldn't be that hard for a dark mode implementation to determine which images are diagrams and which are photos, and switch the colors for one class of images and not the other.


Rust analyzer is a game changer. Try it today if you haven’t already.


+1

Not only is it infinitely better than the default RLS, it's honestly one of the better IDE experiences I've ever had in any language period. In particular it has novel features like inline labels for inferred types, argument names when calling functions, etc.


I’m also very impressed with the rate of progress. They are moving very fast and I can notice a pretty big improvement regularly.


As one of the managing people at Ferrous Systems, I’d like to mention that the pace of development is very much only possible because of the sponsors of the project, both individuals and corporate and some paid for feature development. This allows us to spend constant engineer hours on the project instead of what’s just left over as well as pay some money to contributors as well. A big Thank You to all of them.


I'm curious how much your architecture also plays into it? I read a blog post you did a few months back comparing the big-picture architecture to others like IDEA, and it sounds fantastic. I've worked on observables-based/unidirectional data-graph style projects before (not compilers), and at least in my experience that paradigm really opens up head-room for productivity


I sincerely cannot comment on technical matters of RA, I wish I could. I’m just the guy that needs to balance the budget :)


That's fair! Keep up the great work :)


The higher order bit here is indeed funding: ides are deep and complex, they need a lot of focus.

The internal architecture (or rather culture) of making the thing easy to work with is also an important factor. For example, this very document is a part of intentional “architecture for ease of development”.

The fancier stuff like incremental compilation with salsa are liabilities: Rust is a complex language, so we have to pull complex tricks to make IDE works. This slows development down, so we compensate by focusing even more on build time, isolating complexity, and reducing interdependencies.


Yes! I follow them on Twitter to keep up with the updates, it seems like there's a new feature every week

Edit: Not sure why you're getting downvoted for making a positive, relevant, and factual statement. Sometimes I just can't figure out what goes on in people's heads when they downvote something.


Rust analyzer gets really close to what the IDEA family of IDEs provides, but it's just not there yet.

Personally I'd have preferred more community investment in an IDEA plugin.


I agree with your general sentiment: there’s a lot of powerful features and de-duplication one gets with a single engine to analyze many languages, a-la IDEA.

At the same time, there’s quite a bit of synergy if you go in the other direction, and provide a unified language specific tooling, especially for languages for which it is meaningful to self-host.

It’s sort-of like an expression problem: no matter how you slice it, there’s NxM cells to fill.

Ideally, one should have both. Incidentally, Rust has both :)

It’s also instructive to compare with LLVM: backhands is where all the languages are the same, frontends is where all the languages are different. It’s pretty hard to invent a “frontend IR”, which doesn’t make all the languages feel the same.


The benefit of the LSP is being able to integrate with any text editor. Focusing on an IDEA plugin would leave behind the many developers who prefer VSCode, Vim, Emacs, etc.


The LSP means every single language server has to reinvent the wheel again and again.

It’d have been much more useful to build bindings for IDEA plugins so they could be integrated into arbitrary editors, especially as the IDEA plugins for most languages even after several years of LSP development are still superior.

All in all it’s like the whole JVM vs. WASM, Java vs Electron story again, with someone deciding to reinvent the wheel but worse.

There’s even bindings like https://github.com/Ruin0x11/intellij-lsp-server or https://plugins.jetbrains.com/plugin/10209-lsp-support to glue it all back together.

It’d have been much simpler to reuse an existing ecosystem from the start.


Presumably IDEA plugins have to be written in JVM languages, and use specific language-level bindings, and I would bet they're not very well decoupled from IDEA itself (which would make it really hard to write adapters to other editors).

Language servers are just that: servers, exposing a very unopinionated API. They run in a separate process, can be written in any language, and can even be hosted from any machine. That makes for a much more open and flexible standard.


Sure, but imagine if the LSP designers had, as first project, just written a binding for IDEA.

Then VSCode could've immediately had all the advantages of IDEA, and we'd be able to use both interchangeably.


I maintain that that would've been much harder to implement, for VSCode and for all other editors that followed. Among other issues, it would require a separate JVM process and some way for other languages to bind directly to JVM interfaces in that process, since most non-Java editors are not written in JVM languages.

If what you're suggesting is an LSP that wraps any given IDEA plugin and maps it to the LSP protocol, well, that can still be done (assuming it could ever be done) and would've still required the LSP protocol to be invented first.

On top of all that: you're welcome to re-use any code out there (in any language!) when writing an LSP. Nothing stops you from leveraging the bulk of an IDEA plugin, or whatever generic compiler utilities go into IDEA, when making your own LSP. I wouldn't say any work is wasted at all.


Same is true for compilers. and actually, modern compilers already include the LSP business logic. Therefore, it is not a waste. Especially since languages exist outside of a single idea system like IDEA


> Same is true for compilers.

Which are mostly collections of dozens of languages and dozens of backends reusing the same functionality in compiler collections like the GCC or LLVM.

Instead, with LSP, every single one reimplements everything from scratch.

And the features available to you differ heavily from one language to another.


> every single one reimplements everything from scratch

Still not sure where you're getting this idea that everything has to be done over from scratch. Code sharing is code sharing; the only new thing that fundamentally has to be written is the mapping to a particular public interface, but that had to be done anyway because no previous interface was generic enough to be used by all possible editors.

As an example: the original RLS mostly just uses Rust's existing compiler internals. It doesn't perform super well, because rustc is optimized for full-build usecases and not interactive/partial usecases. But it didn't have to be written in a clean-room environment just because it's exposing a new API to the outside world.


Rustc has code to refactor-rename variables across multiple files? Code to extract the implementation of a function out into a separate file? Code to turn duplicated code automatically into a macro?

The significant task in a language server isn't the "parse and show types" part but the "provide resharper-like refactoring functionality".

And every single language server has to reimplement all these from scratch.

And every single language server ends up with slightly different refactoring functionality, no standardisation or anything.

Compare that to IDEA, where changing the type of a function at one point, and propagating that change to all calling functions across the whole code base is a single key stroke — and always the same, no matter which language you use.

That's what I'm complaining about.

LSP is an improvement for editors, but significantly worse than the alternative for actual IDEs.


>And every single language server has to reimplement all these from scratch.

This is mostly true about IDEA as well. Take a look at the extractFunction implementation from IntelliJ Rust:

https://github.com/intellij-rust/intellij-rust/tree/6b2c4dfa...

It is based on a generic `RefactoringActionHandler`, and not on the specialized `ExtractFunctionActionHandler`.

There's relatively little code sharing you can do for high-level things in IDEs.

The use interface sharing is another thing, and that is exactly what LSP achieves: it standardizes common actions across many languages.


IDEA has a language-server plugin: https://github.com/gtache/intellij-lsp

Personally I hate using IDEA because it's too sluggish for my taste. With language servers I can pick whichever IDE I want (which for me means VSCode, which is about as snappy as it gets outside of text-mode editors) and still have rich language integration.


It is, with RLS I always felt it was what kept me from really liking programming in Rust. Since I don't program Rust every day it would be looking up everything. Now with rust-analyzer it's fast and exact enough that I can stay in the flow.


Is it possible to get the inline inferred type annotations to show up in Vim the way they do in VSCode?

I have been making a strong push to move to 100% Vim for development, but those inline annotations in VSCode with rust analyzer are amazing, especially while I'm still learning Rust.

I'm currently using YouCompleteMe with rust-analyzer, plus rust-vim for autoformatting


I use coc.nvim with rust-analyzer and I find it amazing. I used a more lightweight lsp client in the past, but I find the more full-featured coc.nvim to be the best balance - I get all the benefits of an IDE + the productivity of vim. coc is based on the VSCode intelli-sense engine and enables inline type-annotations by default, but I am not sure if "regular" vim (not neovim) supports it.


Can you please share your config? I find configuring coc quite painful.


I actually find configuration really nice with json auto completion. My config is here: https://github.com/ibraheemdev/dotfiles/tree/master/.vim.


Thank you!


Take a look at neovim 0.5 beta [0]. It has native support for LSP [1], and it's on par with other editors. Also, the setup is nearly zero overhead, as there are default configs [2] that others maintain.

[0]: https://github.com/neovim/neovim [1]: https://neovim.io/doc/user/lsp.html [2]: https://github.com/neovim/nvim-lspconfig


Curious about your thought process to leave VSCode for vim? I've been a long time vim user, but I've seemingly just surrendered to the ease of installing high quality extension in VScode. Just seems to work as advertised without me toiling in some config setup (vimrc)

I use the Vim extension in VSCode for editing with my vim muscle memory, even though it has occasional snags/surprises


I really left IntelliJ (Python and Go) for Vim. I wanted to give Vim a good try anyway. My motivation was how ridiculously heavy IntelliJ is on resources

I was doing Rust in VSCode and liked it but the Python support in VSCode was pretty terrible, and Go was so-so (Refactor/Rename tends to rename about 50% of the occurrences if you're lucky), so I wanted to try to concentrate everything in one editor.

The downside for a language like Python without strong type system is the need to use the debugger super often, and I haven't gotten my command-line debugging chops up yet. The IntelliJ debugging experience is really, really nice.


Rust-Analyzer is much better than whatever IDEA/Clion uses IME.


You have to consider that both plugins were pioneered by the same lead developer, and rust-analyzer came as a second system leveraging things learned from the IntelliJ Rust project.


Is there anything other than performance and proc macro compatibility that RA has over IntelliJ-Rust? All of the alternatives to IntelliJ-Rust are just missing critical (to me) features like refactoring.


RA uses chalk [1], which is a trait solver rewrite for rustc. You can already use it on nightly with a feature flag.

So RA can get close to the trait resolution of the compiler, which is probably the most challenging part. I haven't used Intellij in a while, but I doubt they can ever get close with their custom implementation. I always had trouble with trait resolution/autocompletion, which is often where you need from the IDE the most.

[1] https://github.com/rust-lang/chalk


When was the last time you tried RA? I ask because they've been adding features at a rapid clip, and lately they seem to be focusing on adding new refactoring features. I wouldn't be surprised to hear they still don't have everything CLion does, but I also wouldn't be surprised to see them get there before long.


I try to install the VS Code Rust plugin every couple of months. Every time, it doesn't work. It does literally nothing. No syntax highlighting, no tab complete, nothing. I look up the issue and there's always some excuse of why it happens to be broken right this second. "The next Rust release will fix it" or whatever.

I've given up and I've been using the IntelliJ Rust plugin, which just works.

I don't know what the Rust Analyzer and RLS teams are doing wrong, maybe it's insufficient QA or something, but it's a huge turnoff when after repeated attempts over a year I've experienced nothing but failure after failure.


Not sure if you were just abbreviating, but my understanding is that there's a "Rust" plugin for VS Code which is not the same as the rust-analyzer plugin, is nowhere near as good and yet shows up first in searches.


I suffered this a year ago and it sucked. But I scraped together help and advice and got it working and now it's just amazing and works perfectly with no maintenance. I'd love to pay it forward by working 1:1 with you to get yours working. I'm free any time during Toronto office hours if you'd like to take up the offer.

And of course if you want to keep using IntelliJ, that's an awesome tool as well.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: