[HN Gopher] Rust-Analyzer Architecture
       ___________________________________________________________________
        
       Rust-Analyzer Architecture
        
       Author : ibraheemdev
       Score  : 207 points
       Date   : 2021-02-04 15:46 UTC (7 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | nindalf wrote:
       | 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).
        
         | [deleted]
        
         | ibraheemdev wrote:
         | 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
        
           | stefan_ wrote:
           | 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.
        
           | Fiahil wrote:
           | 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 !
        
           | User23 wrote:
           | 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.
        
             | pimeys wrote:
             | 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...
        
             | zxv wrote:
             | 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
        
             | umanwizard wrote:
             | 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.
        
             | saghm wrote:
             | 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.
        
       | pbw wrote:
       | 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.
        
         | krut-patel wrote:
         | "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.
        
       | adamnemecek wrote:
       | Rust analyzer is a game changer. Try it today if you haven't
       | already.
        
         | brundolf wrote:
         | +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.
        
           | kuschku wrote:
           | 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.
        
             | ibraheemdev wrote:
             | 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.
        
               | kuschku wrote:
               | 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.
        
               | brundolf wrote:
               | 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.
        
               | kuschku wrote:
               | 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.
        
               | brundolf wrote:
               | 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.
        
               | oaiey wrote:
               | 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
        
               | kuschku wrote:
               | > 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.
        
               | brundolf wrote:
               | > 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.
        
             | matklad wrote:
             | 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.
        
             | brundolf wrote:
             | 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.
        
           | adamnemecek wrote:
           | I'm also very impressed with the rate of progress. They are
           | moving very fast and I can notice a pretty big improvement
           | regularly.
        
             | Xylakant wrote:
             | 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.
        
               | brundolf wrote:
               | 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
        
               | Xylakant wrote:
               | I sincerely cannot comment on technical matters of RA, I
               | wish I could. I'm just the guy that needs to balance the
               | budget :)
        
               | brundolf wrote:
               | That's fair! Keep up the great work :)
        
               | matklad wrote:
               | 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.
        
             | brundolf wrote:
             | 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.
        
         | carlmr wrote:
         | 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.
        
       | skrtskrt wrote:
       | 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
        
         | ibraheemdev wrote:
         | 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.
        
           | ruph123 wrote:
           | Can you please share your config? I find configuring coc
           | quite painful.
        
             | ibraheemdev wrote:
             | I actually find configuration really nice with json auto
             | completion. My config is here:
             | https://github.com/ibraheemdev/dotfiles/tree/master/.vim.
        
       | zbowling wrote:
       | 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.
        
         | monadic3 wrote:
         | 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.
        
           | the_duke wrote:
           | 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.
        
           | ibraheemdev wrote:
           | 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...
        
           | matklad wrote:
           | 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.
        
           | Nullabillity wrote:
           | At least in Emacs, it shows the type as a tooltip if I hover
           | over the closing paren of a function call.
        
             | CryZe wrote:
             | Works in VSCode too, not sure what specifically their
             | problem is.
        
       | solmag wrote:
       | Rust-Analyzer is much better than whatever IDEA/Clion uses IME.
        
         | lights0123 wrote:
         | 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.
        
           | the_duke wrote:
           | 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
        
         | atsuzaki wrote:
         | 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.
        
       ___________________________________________________________________
       (page generated 2021-02-04 23:00 UTC)