Recent Updates in IntelliJ Rust

While CLion and all our other JetBrains IDEs were making the transition from version 2019.2 to version 2019.3, the IntelliJ Rust team has been busy making important updates to the plugin. In this post, we would like to give a summary of all the features that have been added over the last few months.

Cfg attributes support

One of the major updates for IntelliJ Rust is the initial support for cfg attributes. Now, the conditionally disabled blocks are excluded from name resolve and code analysis and are grayed-out in the editor.

At the moment, the plugin only recognizes a limited set of cfg options – other options, including test, are still considered unknown.

Cfg blocks highlighting

Cargo features declared in the project’s dependencies are supported as well, and handling workspace features defined in your Cargo.toml is a work in progress.

As a handy bonus, the plugin provides completion inside cfg attributes to help you quickly fill them in:

Completion in cfg attributes

Include! macro support

A few revisions back, IntelliJ Rust started to support three common uses of include!: you can pass string literals, concat!, env!("OUT_DIR"), and combinations thereof as input arguments and get full code insight in both the including and included file.

For IntelliSense to work correctly, the include! call should be located in a module (not inside a function).

Include macro support

When you include files using env!("OUT_DIR"), code insight has to work on the code generated at compile time. Currently, you need to manually enable this feature by setting org.rust.cargo.fetch.out.dir in Maintenance (Ctrl+Shift+Alt+/ on Windows/Linux, ⌥⇧⌘/ on macOS) | Experimental Features:

Enable fetching OUT_DIR for include macro

This functionality is disabled by default due to an expensive side effect from the command that is used for retrieving the OUT_DIR variable, cargo build --build-plan. On the next build, this command forces the whole project, including all the dependencies, to recompile.

New features of the experimental macro expansion engine

The plugin’s experimental engine for macro expansion gets more and more features with each release. Just a quick reminder: to turn it on, go to Settings | Languages & Frameworks | Rust, and change the Expand declarative macros option.

The experimental engine provides code insight for macro calls, and it now covers the cases when your macros generate modules and implementations. The generated blocks are properly highlighted, and you get completion and navigation inside the generated elements:

Code insight for macro calls with modules

Also, you can use Type Info (Ctrl+Shift+P on Windows/Linux, ⌃⇧P on macOS) and Extend Selection (Ctrl+W on Windows/Linux, ⌥↑ on macOS) in macro calls. Both actions work as they would if they were applied to regular out-of-macro code:

Type Info and Extend Selection inside macro calls

And in addition to this, you can view macro-generated items in the Structure popup (Alt+7 on Windows/Linux, ⌘7 on macOS):

Macro-generated elements in Structure view

As a part of these improvements, the plugin now takes arbitrary macros into account when performing type inference. Previously, only the top-level items and certain commonly used std macros were processed correctly, causing a false-positive “Type mismatch” in some cases.

Type inference for arbitrary macros

Not only does the experimental engine bring more functionality to macro expansion, but it also consumes a lot less memory and works significantly faster than the default engine. Performance improvements, especially those affecting name resolution and type inference, have resulted from the major rework of the plugin’s cache subsystem.

Other improvements

When code generating actions and quick-fixes (like Implement members, Specify type explicitly, or Add remaining patterns) produce symbols that require additional imports, you no longer need to call Import manually. This handy quick fix now works automatically as you type:

Auto-import for code generating actions

New interactive inlay hints can help you navigate through complex declarations even when they include type aliases for enums and structs. Hover the mouse over a hint with the Ctrl key pressed to unfold the type and choose the element you want to jump to:

Inlay hints

Now that code coverage is available in CLion, you can use it for your Rust code as well. The implementation of coverage analysis is based on the grcov tool (which the plugin will prompt you to install).

Code coverage results

There are also a few enhancements for the toml support provided by the IntelliJ TOML plugin. For example, the paths in Cargo.toml are now equipped with completion, navigation, and certain refactorings:

Completion and navigation for paths in Cargo.toml


That’s it for the recent updates in IntelliJ Rust! If you have any questions, please ask them in the comments below or ping the team in gitter. For bug reports and feature requests, don’t hesitate to create tickets in the plugin’s issue tracker.

Thank you for reading and stay tuned!


Your Rust Team
The Drive to Develop

image description