IntelliJ Rust News

Updates in IntelliJ Rust for 2021.3

In this release cycle, we focused on enriching language support and adding more code insight features. The run and debug functionality has received a few major updates, too. Read on to learn the details.

Language support

Code insight

Run and debug

Language support

Macros 2.0

IntelliJ Rust does its best to keep up with how macros 2.0 are evolving. Two of them, addr_of and addr_of_mut, have already been added to the Rust standard library and can be used with stable toolchains.

Now, if there are macros 2.0 in your code (for example, std::ptr::addr_of), the plugin will expand them properly and resolve the names. You will get completion, quick documentation, and other code insight features for them, and annotations and quick-fixes will be available as well:

Macros 2.0 annotations

Macros 2.0 are marked with a special orange icon to help you distinguish between them and regular declarative macros (their icon is grey):

Macro 2.0 icons

Procedural macros

We are also continuing to add more features for procedural macros, which we announced a while ago.

The plugin is now capable of expanding procedural attribute macros so that all the expanded items are included in type inference and name resolution. However, the implementation for this is in the early stages of development, so there may be unexpected behavior.

Attribute procedural macros

As for custom derive macros, all of the items generated by them are now taken into account. Previously, the plugin could only properly work with the generated impl blocks.

Note that procedural macro support is still experimental and disabled by default. To turn it on, call Help | Find Action (Ctrl+Shift+A on Linux or Windows, ⇧⌘A on macOS), search for Experimental Features, and enable two flags: and org.rust.macros.proc.

Experimental features to be enabled for procedural macros

Make sure to reload your project afterwards via Refresh Cargo Projects in the Cargo tool window.

New syntax contracts: let else and if let guard

IntelliJ Rust now supports two new syntax items, which are currently available in nightly toolchains (in stable toolchains, the plugin will mark these items as experimental compiler features).

  • let else is a new let PATTERN: TYPE = EXPRESSION else DIVERGING_BLOCK; construct, which simplifies common error-handling patterns. It’s a counterpart to if let.

    Support for the 'let else' syntax

  • if let guards are conditions specified after the pattern in a match arm that must match in addition to the pattern in order for that arm to be chosen:

    Support for the 'if let guard' syntax

Full stdlib info fetching

The plugin now fetches all information about standard library packages, including their dependencies, editions, and Cargo features. With this on hand, IntelliJ Rust understands the stdlib structure much better in a variety of cases, allowing it for example, to build a proper list for completion suggestions and provide navigation for the items defined in the std::os module:

Completion for the std::os items

Did you notice the arrows next to the completion suggestions on the screenshot above? They mark the entries that were reordered according to the sorting provided by ML completion.

If there are any errors during the stdlib data fetching, the plugin will report them in the Sync tab of the Build tool window.

Code insight

Auto-import updates

The new name resolution engine now supplies data to the Auto-import quick-fix and completion for items out of the current scope. This makes auto-import available for macros and improves the processing of complex re-exports, all while boosting performance.

Auto-import updates

Improvements to the Unused import inspection

Unused import detects when there are use statements that don’t affect your code and suggests a quick-fix to remove them. Now it detects unused imports even for modules with nested submodules:

Unused import annotation

At the moment, this inspection is disabled by default due to a number of false positive warnings. You can enable it at any time in Settings / Preferences | Editor | Inspections | Rust:

Unused import inspection settings

ML-assisted completion

Completion based on machine learning data has been enabled by default. The suggestions you get in the completion list are sorted according to the data gathered anonymously during the IDE’s Early Access Program. We want to emphasize that your source code is never collected – only information about your interactions with the code completion UI.

To learn which elements were actually reordered by the ML algorithm, tick the Mark position changes in the completion popup checkbox in Settings / Preferences | Editor | General | Code Completion.

ML completion sorting

If you prefer to disable the ML completion feature, clear the corresponding checkbox in Settings / Preferences | Editor | General | Code Completion.

Extract struct fields

You can now quickly extract selected struct fields into a separate struct. You can call this feature via an intention action (select it from the list of the ‘lightbulb’ options) or as a refactoring (call Refactor This via Ctrl+Alt+Shift+T on Linux or Windows, ⌃T on macOS).

Extract struct fields

Quick-fix to qualify paths

This new quick-fix will fully qualify an unresolved path with an import candidate:

Quick-fix to qualify full paths

Completion with local crates indexing

Completion for dependency names and versions in Cargo.toml has been improved significantly thanks to indexing of the local metadata.

For example, previously, if you wanted to add the tokio-tungestine library, you might have needed to invoke completion more than once in order to get the proper entry in the list of suggestions. This was because the plugin had to send a separate request to every time completion was invoked. It now knows all of the possible variants beforehand, which allows all the options to appear in completion right away:

Completion with local crates indexing

This is a starting point for the implementation of more code analysis using local crates indexing. If you are interested in following our progress on this feature, keep an eye on this meta issue.

Run and debug

For a summary of all the recent debugger updates, see our previous blog post about them.

WSL support

In this release cycle, we enabled WSL support by default. You can use it with the plugin in any of the compatible IDEs, but debugging is available in CLion only.

When working with WSL, make sure to set the WSL toolchain location in Settings / Preferences | Languages & Frameworks | Rust. You can select from the detected toolchains or provide the path manually:

Detected WSL toolchain

To debug on WLS in CLion, you also need to switch to a WSL toolchain in the CLion settings:

WSL toolchain in CLion

Break on panics

When a panic occurs in your application, the plugin’s debugger will stop inside the panic! call automatically, even if there are no breakpoints. This can help you investigate the stack trace and variable context around the point of panic.

Breaking on panic

This feature is enabled by default. If you prefer the debugger not to break on panics, go to Preferences | Build, Execution, Deployment | Debugger and clear the corresponding checkbox.

One last notable update is that code coverage now works for both nightly and stable toolchains.


We want to thank the external contributors who have helped us in this release cycle:

That’s it for the changes we’ve made in IntelliJ Rust over the last few months. Please share your feedback here in the comments, and don’t hesitate to report any issues in our tracker. We also encourage you to take a look at the plugin’s documentation.

Thank you for reading, and stay tuned!

Your Rust team

The Drive to Develop