I used RLS 1.0 (through the VSCode RLS plugin) for a year or so before discovering rust-analyzer, and I just want to say, even in pre-alpha it is an astonishingly huge improvement. If you do Rust development, do not wait to upgrade. Type checks are instant. Inferred types get previewed inline, also instant. Autocomplete works as expected. Type errors are localized, which might have been my biggest frustration with the old RLS. In terms of developer experience it's like using a whole other language.
I tried Rust a few months ago and I was a little dumbfounded on how little 'modernity' I felt (regarding the IDE experience) compared to what several articles told me I should expect when using Rust with, for example, Visual Studio Code.
Last month a project with requires the development of a high performance event collector came in, and I decided it was time for us to go to the Rust side. Again, I redid my dev setup with VSCode but this time I used rust-analyzer, and oh boy.
"What, I now have practically instant inlay typings as I type a line of code??"
e.g: "let x<: type> = ..." type inlay changing dynamically as I instantiated the object on the right hand side.
So if you just like me got little winded at the sheer complexity of the whole Rust thingy and decided to wait a little more to dive in, let me tell you: rust-analyzer makes the whole thing way more palatable.
Fast forward a WEEK later and I have a multithreaded message passing, postgresql consuming backend prototype to show the guys. It is very performant and consumes about 2 megabytes of ram while running and providing a continuous streaming websocket info feed to the to-be-developed dashboard that we are doing.
Rust is awesome. and better tooling is going to make it soar even higher.
Yes. And the thing is, because Rust is such a complex-to-compile language, and because there's all this discussion around its slow compilation times that they're working to improve, I just assumed the whole time that "well I guess this is the cost of having such a powerful type system". I didn't question how terrible the editor experience was. But now I see how much better it could've been!
I know the Rust team is hard at work, and I know they have a lot on their plate, and I'm very grateful for the work that they do. But I think it was a mistake to de-prioritize the editor experience for so long. It may have permanently turned off lots of people to Rust because they tried it and assumed the language was just too hard, when in reality they were flying blind. The compiler messages may be known for being great, but many people, especially newer devs figuring out a language, don't sit there with a compiler open while they explore what is and isn't allowed. There's much more to the dev experience than the compilation experience.
I'm not a compiler writer myself, but my impression is that designing a compiler "the traditional way" and designing one "the IDE way" look really different. Most people who learned to write compilers 10 or more years ago learned the traditional way. As a new language, Rust benefited from a lot of obvious-in-hindsight things, but "design your compiler for an IDE first" just hadn't reached quite the same level of obviousness by 2010.
You are right. Even today, my impression is that most CS students taking compilers and PL courses are still taught in the "batch mode compile the world" way. Most textbooks still assume that too.
It's somewhat understandable because the way you architect a compiler for an IDE is a lot more complex. It's basically everything that's hard about a compiler plus everything that's hard about data validation, and everything that's hard about caching and cache invalidation.
But, yeah, there's a big gap between industry and academia with regards to how to architect an IDE/compiler.
I think IDEs make things look more complicated than they actually are. Especially new students have trouble understanding what the difference between a programming language and a programming environment is, because they are exposed to them as one unit.
Keep in mind that Rust was already trying to figure out what the language itself was supposed to be and even if the whole lifetime analysis would work once they landed on it as a possible solution. Making a compiler suitable for an IDE from the beginning is much harder (but can inform language design). If you compare the output from rustc 1.0 to any recent version you will see how much of the work needed for a production compiler is at best tangentially related to what people consider the raison d'être for a compiler.
> As a new language, Rust benefited from a lot of obvious-in-hindsight things, but "design your compiler for an IDE first" just hadn't reached quite the same level of obviousness by 2010.
The whole idea of a "language server protocol" is relatively new. And it's why VSCode is absolutely killing it in a lot of spaces.
A "language server protocol" is ... kind of obvious? But it requires a lot of power behind it. It also requires languages whose grammars are optimized in such a way that they don't have to compile the universe to figure things out (see: C and C++)
How did IntelliJ handle things? Did they do something analogous?
Anders Hejlsberg explains explains how “the IDE” way compiler works. First ~10 minutes is traditional compiler background. Then about ~8 minutes before he starts talking about how an IDE focused compiler works: https://www.youtube.com/watch?v=wSdV1M7n4gQ
As someone who knows very little about compiler implementation but has some interest in it, I'm curious what makes the difference between the two in terms of architecture
Basically the IDE one needs to take into account that your program is broken all the time, yet you want code completion for everything else that is actually correct.
Also it needs to respond immediately after asking for completion, as anything beyond 2s is frustrating development experience.
You also want to get real time errors and warnings, just for the parts that are actually broken, not a wall of text like many batch compilers that fail to understand the remaining of the file.
Also you want to be able to do code refactorings, regardless of the compilation state.
So basically you want a Smalltalk/Lisp Machines like experience.
It not only informs the architecture but also the language design. For IDEs you want quick response even if it is not perfect, for a compiler you want correctness over everything else. The language having syntactic redundancy can help an IDE parser recover gracefully from a typo or missing tokens. Having semantic negative space can let an IDE recognize intent for code that looks correct from extrapolated understanding that is actually not semantically correct, and suggest solutions.
rustc already tries to do all of these strategies, but blows the latency budget because it still prioritizes correctness over everything else.
My understanding is that the "traditional way" is based on a number of "passes". In my head it looks like:
1) Parse all the code.
2) Assemble the set of all types.
3) Typecheck all the code.
4) Translate the parse tree into unoptimized machine code.
5) Optimize all that machine code.
This is oversimplifying things, as in practice there are intermediate representations between the parse tree and the machine code. And optimization itself usually involves multiple passes of different kinds. But anyway, the key point here is that, if you change any of the code, you have to run all of these steps all over again. (I'm oversimplifying again. Maybe you only have to rerun them for a given "compilation unit", but that's bad enough.) This is the opposite of what you want for an IDE. There, you want to say "I just changed this function. Please recompile the absolute minimum necessary to tell me whether my change works." To answer a question like that efficiently, you have to rearchitect the whole compiler from being pass-based to being query-based, so you can give it instructions like "please update the type of just this expression".
There was no conscious choice to de-prioritize IDE integration. Folks have been working on it for a long time; the rls has been on the stable distribution since september 2018, for example. There is always more work to do than there are hands to do it.
It is not-trivial to re-architect a near-million LOC compiler, while also still doing all of the other things that the project needs.
Apologies if I came off as ungrateful, that was not my intent. I don't know the inner-workings of the project's prioritizations; I just, from the outside, haven't seen much movement on the language server in the time I've been using Rust and assumed it was because some of the other (many!) things that were being worked on had taken attention away from it.
It's all good; I think in some cases it's a distinction without a difference. Like, it is true regardless of the why, we have had a less than stellar IDE experience. Saying "we do care about this" only does so much to help; it gives you hope for the future, but doesn't change the facts on the ground.
I have just set up my Rust environment on a new machine and installed RLS. Even on a new Ryzen 3600, RLS isn't the greatest experience. I'm very exited to try rust-analyzer now.
I'd just chime in to say that Rust-Analyzer is an awesome tool that really helped me as a Rust beginner. Having your text editor show the types of everything, highlighting the mistakes you made or suggesting functions right after you keypressed a dot is awesome to discover all the features Rust offers you as a developer.
Can’t wait for rust-analyzer to graduate as an even more fully featured LSP – it has the potential to really changes the daily life of thousands!
One thing I find astounding about this project is the breakneck pace of development. I keep up with the weekly changelogs and subscribe to the nightly builds. Its genuinely impressive how much this project has achieved and the rate of new features being produced.
Thinking back to some of the RLS blogposts about the need for something like rust-analyser from about a year ago I'm pretty sure nrc (Nick Cameron) said it would take about 2-3 years to reach this point. However, I'd say rust-analyser has been usable and better than RLS for many months now.
I think that year comparison doesn't work super well; some of the work done in the compiler over the past 2-3 years contributed here. rust-analyzer (in my mind) would not have been possible in the same way at the time the rls was built. It would have needed to do a lot of the work that's been ongoing in the background since.
I love the homage to IntelliJ Rust in this article!
As a newbie computer science major who "grew up" in the era of Eclipse/IntelliJ conversion, IntelliJ will never cease to amaze me in how much more productive I became with IDE tools and the general "power behind the compiler".
Mad props to the plugin interface JetBrains has provided and the novel solutions that have come out of this style of thinking that far outpaces the experience in something like Xcode.
I love IntelliJ's backends - they are best of breed for sure.
However I think its editor is subpar and not very customizable. I also dislike its simple vim mode.
I really wish I could pay for IntelliJ's backend with my desired editor. It's a shame IntelliJ didn't embrace LSP and work with the standard. I think eventually this will come to hurt them, because it just motivates those who want a better editor to build their own LSP backends.
I have already dropped IntelliJ for almost every language because the LSP servers have gotten so good. The only languages I'm unable to avoid are the big JVM languages (except for Clojure). But one day someone is going to build a great JVM LSP and then I'll drop my IntelliJ subscription once and for all.
The main problem I find is mixed language projects are not well supported like they are in Intellij. For example I'm working on projects using gradle and mixing Groovy and Java. In the past I was working on Scala/Java projects with sbt. None of these combinations are well supported by an LSP server. I think we need a polygot JVM LSP server that can support multiple languages and build tools seamlessly (just like IntelliJ can...).
I'd love to read an article that compares capabilities of the two! Martin Fowler seems to think otherwise:
> I was known for my annoying habit of stating how Smalltalk's IDE was better than anything I'd seen. No longer. For me IntelliJ was first leap forwards in IDEs since Smalltalk.
Not that I disagree with you, but 2-6 basically come down to "it lacks a Lisp-like REPL."
I do think that the REPL workflow is way underappreciated and missing in Intellij. What I like about it is that it still focuses on working on semantic intent rather than editing text. In this way, it's similar in some sense to the idea of working on S-expressions rather than text.
The performance and stability improvements in rust-analyzer over the last six months have been remarkable. Kudos to matklad and the whole team behind this. I'm using it full time now.
Does anyone know how the Rust-Analyzer compares to the Rust Intellij plug-in? From the article it seems that Intellij uses their own custom solution.
I've been playing with Rust for the past couple of weeks, and I've really enjoyed the working with the language. The documentation and community are top-notch. The biggest downside from moving from a language like Java or Typescript (which I use in my day job) is the IDE experience. Things like code completion for other crates (which you'd take for granted in some of the other languages) don't seem to work.
Personal Anecdote: Every time I've tried using rust-analyzer in another editor I've ended up going back to CLion (an IntelliJ-based IDE from JetBrains). The CLion experience is far superior in my personal experience. The speed difference is barely noticeable on my system while the completions, etc. are far more accurate with CLion. For example, with rust-analyzer on one of my projects, it sometimes suggests hundreds of possible completions for in a certain context whereas CLion (accurately) only suggests a handful. The integrated debugger support has been quite nice too.
I would say rust-analyzer has less features, but is more performant. For instance, RA works on rustc codebase, while intellij doesn't (the last time I checked).
I use CLion (same rust plugin as IntelliJ + debugging support) for rust development, and overall I would say the experience is pretty good. Certainly basic things like code completion from crates works; something is wrong with your setup if that's broken.
I've also seen huge improvements in the plugin over the past couple of years, such that most stuff just works now. Still some issues with macros (a hard problem in general, limited refactoring support, and occasional analysis failures, but I find it's a hugely productive environment.
(Also, as a bit of history, Aleksey Kladov who was the main developer on the intellij rust plugin went on to create rust-analyzer.)
I tried it recently and I know it's just alpha right now but something feels a little fundamentally annoying about the way it changes things in the editor while you're typing. One example is that it seems too eager to claim something is a syntax error before you've really finished really typing it.
Is rust-analyzer's relative modernity a symptom of intrinsic limitations behind Language Server, or tactical limitations of RLS?
I was very hopeful about the bright future of language server, and its ability to solve that N^2'd problem between editors, addons, and languages. But, if it can't provide truly great experiences outside of Typescript (which has been my unfortunate experience), it does not bode well for the project.
I must say I don't fully understand your original question, so I can't answer it directly. However, I can share my (very hand-wavy) thoughts on the general LSP ecosystem, and it looks like that might actually answer your question.
I personally don't believe that NxM is a real problem. If you have an editor, which has bespoke APIs for providing completion, and a language server, which speaks bespoke protocol, binding the two together is not hard. A single person can do that and if, say, at least 1000 people use editor X with language Y, it doesn't seem like a waste of effort to me.
The problem is that writing a language server that works is hard. "Rewrite your entire compiler from scratch" kind of hard. Before LSP, only JetBrains delivered these kinds of compilers consistently. Notable non-JetBrains tools from before LSP era are Roslyn and Dart Analyzer.
The Dart Analyzer project is particularly interesting -- it's the same "separate server process speaking JSON" kind of architecture. The details of protocol are different (as it predates LSP) and it doesn't try to be language agnostic. Dart support in IntelliJ is powered primarily by this server.
In my mind, the main value of LSP is social: it pushes language designers and compiler writers to think about editing and refactoring incomplete code, which is a very different problem from compiling mostly correct code.
The latter. rust-analyzer implements the language server protocol like RLS.
RLS was implemented using the compiler as a library, which meant it inherited the compilation model of the compiler, which isn't really well-suited for IDEs. That was done in full knowledge of that drawback.
The advantage for RLS is that it has perfect parity with the language.
Is there a tutorial for how to get this working in vscode? I installed the extension, but it doesn't seem to be doing anything. I tend to have a workspace with a bunch of folders in it, and it seems like rust analyzer only works with a single rust folder in your workspace and nothing else? At least it's throwing a lot of errors indicating that.
I also had trouble getting VSCode workspaces to work (i.e. multiple project roots.)
Also at times, when adding a new crate dependency to Cargo.toml or installing a rust-analyzer update, it seems necessary to reopen the VSCode project (not restart VSCode itself) to get it to work again.
This said RA has been indispensable over the last few months, thank you to the authors!
I had to uninstall RLS in VSCode, install the "default" profile for my toolchain (nightly), and then when I opened a folder with a `Cargo.toml` file, in the bottom right it prompted to install the rust-analyzer server, which I did. Then it started checking everything and I was off to the races.
I'm currently going through https://github.com/LukeMathWalker/build-your-own-jira-with-r... and had been using RLS. I just switched to the VSCode rust-analyzer plugin, I've followed the instructions, the installation finished w/o errors, but it's only working in the main.rs file.
What's the reason the title was changed? I'd prefer to not fall afoul of whatever rule it is in the future, and I think this title removes the interesting part.
I see. Previously, those people had to compile from source, and very very recently, it moved to providing easy installation. So I think that it's not misleading, but I think a reasonable person could differ.
Nah, it was the title change. I'm a super big fan of the previous discussion links; I know they have a weird controversial history on HN, or at least they did a long time back, but I've always thought it was a nice touch.
Okay it's been 3 minutes since I made this post and I've already uninstalled RLS and started using rust-analyzer. It just works out of the box and all my issues with RLS are gone. THANK YOU!
I gave up on Rust 5 years ago because IDE experience was so inferior to C#, maybe it's time to try again.
I really hope that Rust team will focus on developer experience more, it's astonishing how thinks like code completion or hot reload improve the enjoyment of writing code.
Improving UX requires them to restructure the compiler and add new features (like NLL) while maintaining backwards compatibility. This is hard and takes time!
Also note that C# is twenty years old and backed by one of the largest corporations in the world. It's pretty rare to get an OSS analyzer that can compete with the likes of Intellij!
I started ramping up on a Rust codebase last week. Intellij is my default IDE so I just continued with it. The plugin seems reasonable enough. It does all the basics like checking types etc.
Do you have access to CLion or just Intellij? I ask because CLion has real debugging support that, to my knowledge, Intellij does not have (CLion has built in ties to GDB that the other lacks).
I pay for the 'Ultimate' edition which means the different language support is available via plugins. At my day job I toggle between GO & Typescript and some JAVA side projects so setup works well enough for me.
I can't speak to CLion. I use the Go debugger daily and I don't have 'GoLand' perse, just the plugin.
I can speak for you; you won't get a debugger with the Rust plugin with IntelliJ. I'm going from memory here, and it's been a few months, but I believe the person working at JetBrains on the Rust plugin said it wasn't going to come out for IntelliJ.
My company is good about buying us tools, so they got me CLion (or, rather, the entire Jetbrains Ultimate Pack or whatever it's called). CLion has made Rust development almost infinitely better than it was just using the Rust plugin on IntelliJ (and this is coming from someone who just uses the Python plugin in IntelliJ even though like 50-75% of his code is Python). I'm a JVM dev masquerading as a Python dev and using Rust for some stuff that Python just isn't up to snuff on (and using the super sweet pyo3 package to make native python modules for it, too). The point is, I get the <3 for IntelliJ; I pay for the super ultimate edition for home use just because I like it _that_ much. But CLion and debugging has made my life so much better than doing it with the Rust plugin in IntelliJ or using VS Code.
Some people are content with log statements, but I'd rather stab myself than debug via logs. It's just not my jam!
Edit: I just thought to note that the CLion + Windows + Debugger game is weaksauce. There may be a way to get it to work in windows, but I don't know a single thing about the Visual Studio build tools or how to get everything to play nice or whatever that might be necessary, so I tried to get it to work through WSL. It worked sometimes, and not others, and I got so frustrated I picked up a Mac for my work refresh rather than another surfacebook, mostly because I was tired of having to jump through hoops to sometimes have a mostly working eventually kinda debugger.
So yeah - nevermind about CLion! I do think it works better than IntelliJ, but it's a subtle, not-easily-quantifiable thing, and it's probably not worth buying it if you're just dabbling and also have IntelliJ Ultimate.
While Ultimate does give you access to all the language plugins, it does not give you access to all the IDE features that the other Jetbrains IDEs have.
This varies from language to language and IDE to IDE, but Idea does not support C++/Rust debugging, even with the language plugins. Only CLion supports them.
I’ve found this true across multiple languages, hence why I bought the full toolbox subscription and use the language specific IDEs where possible. It’s cut out a lot of rough edges from when I tried to just use Ultimate.
I don't think there is any good IDE that offers debugging and good IDE experience on windows (msvc) at the moment. CLion has had debugging but not for msvc last time I checked.
Perhaps VSCode can be combined with Rust-analyzer to give language support on par with IntelliJ-rust, but also a msvc debugger? That would basically make windows development "feature complete" (and free!).
rust-analyzer works well on Windows; I don't do a ton of debugging though. (I have been windows only for the past few years, but am not really an IDE person)
The best way to install it is by installing the VSCode plugin, it will download the binary for you. rustup may arrive in the future and make things better for other plugins.
Thank you for letting me know about that. Last time I gave it try it required building the analyzer and then installing the extension manually. The process is much less tedious now.
It's not part of rustup. At least for the VSCode plugin, it'll prompt you to download when it first runs. As long as you've got a working rust installation it'll work pretty seamlessly in my experience.
Is my impression or this could lead to a kind of "rust-in-time" compiler? If the idea is to have a "roslyn" kind of backend then generate on the fly rust code and run it directly is feasible?
Sometimes rust-analyzer stops working. It seems to be related to how many projects you have open. I wish there was like a ui that would allow me to disable it for some projects and enable it for others.
You can. Projects in VSCode are called "Workspaces".
Every time I install an extension, I first "Disable" it, which is global. Then I switch to the workspace that needs it and choose "Enable (Workspace)". That way you only have the extensions you need per project.
I only ever have 1 project open at a time then switch to which ever other project I need to (RLS had the same issues), vscode makes this easy to do with ctrl+r but I don’t know what IDE you’re using.
They're webm, so if your browser doesn't support that format, it won't play. Safari being the last main one to not support it, so if you're on that, that's why.