IntelliJ Rust 0.2.0 released

Hello!

It's been a while since the previous IntelliJ Rust update, so it's a high time to give a summary of what has happened since then!

First of all, the plugin is officially supported by JetBrains: https://blog.jetbrains.com/blog/2017/08/04/official-support-for-open-source-rust-plugin-for-intellij-idea-clion-and-other-jetbrains-ides/. Now two people from JetBrains, vlad20012 and me, are working together to make it great!

The greatest recent improvement is a much better support for Rust type system, implemented by Vladislav. Now we handle generic types properly, so code completion and navigation are available inside lambdas, iterators, futures and such.

Our Cargo integration story has improved: now it is possible to link more then one Cargo project to an IDE project, even if you don't use workspaces. There's also a dedicated Cargo toolbar, which shows projects status. Also, Run Configurations and Run Cargo command actions now provide code completion for the Cargo command line based on the currently opened project.

There's also a preliminary debugger support in CLion.

Some other miscellaneous improvements and features include

  • Parameter names and local variable type hints.
  • Better navigation with ability to search for implementations by type or trait.
  • Ctrl+F9 to build project in IDEA.
  • Ability fill an impl types and functions based on trait (video).
  • Support for moving syntactic elements up/down (Ctrl+Shift+Up/Down) and left/right (Ctrl+Shift+Alt+Right/Left) (video).
  • Quick definition (Ctrl+Shift+I).
  • Highlighting of function's exit points, and semantic highlighting.
  • Typing assistance: join lines (Ctrl+Shift+J) cleanups commas and blocks, semicolon is inserted after return automatically in unit-returning functions, completion for function calls inserts parenthesis.
  • Breadcrumbs.
  • Completion and navigation for macro definitions.
  • Introduce variable (Cltr+Alt+V or .let postfix template).
  • Various new inspections and intentions.

Thanks a lot to our awesome 58 contributors!

Some useful links:

51 Likes

Thanks for the great afford. There is one thing taking me back from using IntelliJ Rust plugin is huge performance issues. 50% of the time cpu is hitting 300-350%. It's a big no if I'm on battery power. I think because of the same reason also syntax highlighting is updating very slow (too slow actually). Note, I'm not running on a low end machine :slight_smile:

2 Likes

Yeah, performance is something that we haven't looked too closely into yet, because we are trying to match compiler feature-wise first!

That said, we do intend to focus on performance until the end of the year, and we've also done some great performance improvements recently (which might be offset by our type inference improvements though :slight_smile: ).

Having specific examples of projects/files, where IntelliJ Rust performs poorly would be super-useful!

3 Likes

Thank you to all contributors for this great plugin. I love it.

Looking forward to more debugging capabilities :slight_smile:

1 Like

Thanks! Still hoping to see debugging support in the community edition one day.

4 Likes

Thanks for the great effort and this really boosts our development much!

I've met a few issues however.

Firstly there might be some regressions as to the new version.
When I updated yesterday, my computer (Ubuntu 16.04) suddenly hanged. This is mostly likely a stackoverflow to me since I assigned Intellij with lots of memory and I wasn't running on other programs that eat too much memory (I had some experience with other Intellij plugins before).

Another issue is that the plugin cannot no longer automatically detects my "standard library". Previously it was working fine. I'm using rustup with nightly Rust.

And another potential bug for all versions: the indexing stops working now and then.
A typical scenario is that after several compilation errors, indexing for File A is valid while for File B it is invalid. And when both files uses a struct or function or constant in another module C, "go-to-definition" will work for FIle A but not for File B, and the "find-usage" in C doesn't work for File B. Meanwhile, the definition/usage within one file seems working all the time.
And sometimes, "Navigate->File" will not work due to some indexing issues.

This issue can be bypassed by "invalidate and restart" intellij. However it is really annoying.

1 Like

Most of this sounds like https://github.com/intellij-rust/intellij-rust/issues/1812 (oups, the link was broken, sorry!) we've changed implementation of our project model recently, and there was some fallout when migrating old projects. Are your projects displayed correctly in Cargo toolbar?

1 Like

Thanks for all the hard work guys! I haven't used all features, but I really see the features around code completion and type hinting and etc.

Thanks again guys!

1 Like

Debugger support would be a deal breaker for me. While I love using Vim for Rust development, debugging has too many weird corner cases with cgdb.

A thought on CPU usage: after using RLS in Vim, I noticed CPU spikes every time I saved the file. Maybe since IntelliJ automatically saves files to disk (IIRC), RLS is responsible for the poor battery efficiency?

2 Likes

I don’t know anything about IntelliJ community internals but how possible/infeasible would it be for someone not on the official team to write an external debugger plugin ?

Coming back to intellij after playing with it about a year ago I cannot believe the progress you’ve made, it’s really incredible, congrats !

But an integrated debugging experience a la java and friends would be totally sublime and enough to make me completely switch from Emacs, etc. for my Rust programming (which is saying something)

3 Likes

We don't use RLS at all, so all performance problems are our own fault :slight_smile:

And your are right about saving to disk automatically: we have a rather elaborate implementation of a "virtual file system", which allows us not to have a "Save" button in the UI at all, while not producing excessive disk traffic and inter operating nicely with tools that expect to find files on disk at the same time.

1 Like

Yeah, it definitely is possible, pascal plugin does this, for example. And it's possible to write plugins to extend our Rust plugin (that is, to get access to Rust PSI, name resolution, type information and such from your own plugin), though our APIs are not stable at all, and are unlikely to be stabilized soon (just yesterday we were discussing an introduction of an "intermediate language" in our plugin).

However, we do plan to use the debugging infrastructure from CLion for Rust, and it would be hard to write a third-party plugin for that, because it's closed sourced and does not have a documented public API :frowning:

which is saying something

Totally understand you, my first Rust project was written in Emacs :slight_smile:

1 Like

I'm guessing since the RLS guys are doing a good job (they also use a VFS: https://github.com/rust-lang-nursery/rls/issues/2), that your performance problems are likely coming from the same root cause.

1 Like

Great work! I appreciate you all.

1 Like

Great job! The plugin is now much more convenient, and code completion is very good for me. Filling trait impls is especially tasty.

The things that slow me down the most:

  • Compiler output is scrolled to the end by default, so I need to manually scroll it up each time I compile the project. It's a huge time loss, and I'm very surprised it's still not dealt with (see the old issue).
  • It would be very nice to have an intent for automatically adding required import at the top of the file (e.g. add use std::collections::HashMap; when cursor is at HashMap and it's not imported). It should also work for types from the current project or its dependencies. The compiler usually suggests an import for a missing type, so the IDE should be able to do that too.
  • Code analysis doesn't see Error and Result types created using error_chain! macro.
  • When the cursor is over a type, add ability to view documentation for the type in browser. Popup documentation viewer (Ctrl+Q) seems to be useless because I can't see the type's methods and navigate anywhere.

Also, when clicking on "run" icons next to tests or main functions, created run configurations are incorrect: Compiler output sometimes doesn't have links to file names because they are relative to the crate, not the workspace root. Created configurations set working directory to the sub-crate path, but they instead should set working directory to the project path and use "cargo run -p crate_name". In this case links seem to work.

More random suggestions:

  • Intent for adding public getter and setter for a private struct field.
  • "Add curly braces" intent on imports should be more convenient for adding new imports: use std::path::PathBuf; -> use std::path::{PathBuf, [cursor here]};
  • There is already an intent for adding impl Name {}, but there should also be an intent for adding impl [cursor here] for Name {}.
  • Code completion suggests "let" and "return" inside a struct literal, which is invalid.
  • Code completion inside struct literals should not suggest fields that are already there.
  • Option to do rustfmt on each save.
  • Make it automatically use rustfmt.toml from the project dir or allow to configure rustfmt.toml path per project.
  • Running a test also results in running tests that include the original test's name.
  • Code completion at #[derive()] should also suggest custom derives (e.g. Serialize).
8 Likes

Excellent, thanks for the bug reports @Riateche!

Created configurations set working directory to the sub-crate path, but they instead should set working directory to the project path and use “cargo run -p crate_name”

It was implemented this way initially because cargo run didn't support --package argument. This is now in stable, so RUN: configurations from context use workspace working directory by matklad · Pull Request #1905 · intellij-rust/intellij-rust · GitHub switches from working directories to --package argument. In general, our handing of working directories is, ... suboptimal at the moment. Will try to fix it soon.

Running a test also results in running tests that include the original test’s name.

This is fixed by pasa (Sergey) · GitHub and should be available in today's release: RUN: Uses --exact flag when generating run configuration for a single… by pasa · Pull Request #1868 · intellij-rust/intellij-rust · GitHub

1 Like

Totally agree, huge time loss for me too.

Also f2 (go to error for me) counts non rust errors like typos. Above would not be a problem if it just went to the first error

Well, there are always things to not like in software.
Personally, I think the plugin is fantastic(although with some perf issues which might be IntelliJ-related because CLion also performs very badly when compared to something like QtCreator), it is already very usable and for me, the productivity gains it brings outweigh issues like the compiler output scrolling to the end(CLion also has this issue btw).

Yeah, there are a lot of rough edges at the moment. I don't know an easy fix to the scrolling problem at the moment :frowning:

I personally use Ctrl+Alt+Up/Down to navigate between compiler errors.

Very happy to see progress being made on this... can you explain what you mean by preliminary debugger support? What is and isn't working? I think the biggest thing missing in the Rust ecosystem is a good reliable debugger. There is one for VSCode but it doesn't seem to work with threads.. which means it doesn't work for debugging my project and is kind of a big deal. And it's a little buggy in general.. or at least was about a year ago. They may have made progress there as well.