IntelliJ Rust Releases

New in IntelliJ Rust for 2023.1 (Part 1)

The time has come to outline the state of the IntelliJ-based IDEs’ Rust plugin as of the 2023.1 release.

In the following paragraphs, we’ll delve into the novelties, improvements, and refinements that our team has delivered throughout the release cycle. Follow the post to learn more about the significant changes and features. If you want to learn more about a particular item’s history and the details of its implementation, you’ll find relevant links throughout the post.

In the article, we’ll focus on several topics, including attribute and functional-like macros improvements and the IDEs’ conjoint code insight capabilities that resulted from them. We’ll also look at the progress in the field of Rust debugging, list the errors that the Rust plugin is now able to conclude, and address the main amendments improving the experience the Rust plugin provides when working with code.

Let’s go!

Language Support

GATs support

In development for several years, the GATs (generic associated types) language extension has been a long-awaited feature among the Rust community. We are happy to announce it is now supported by the Rust plugin. With the GATs release, associated types inside traits might capture generic parameters from the same trait methods in the form of lifetime or type parameters. The plugin now renders generic parameters for associated types in the Implement Members inspection.

In order to support generic associated types, we were required to update inspections for Rust type aliases and add changes to the internal parser itself. This allowed us to discern generic parameters for associated types and associated type bounds, as well as support where keywords, a common usage pattern for GATs. All this was done to gradually advance the Rust plugin so that it’s able to make basic type inferences for GATs.

Support for generic associated types is an ongoing task that continues to be refined. You may also consider contributing to our efforts by providing us with a problem description or suggestion regarding the recent language support feature.

Disable completion and auto-import for specified items

Controlling which item’s paths are auto-imported and participating in completion machinery are now possible thanks to the supplement table, which you can access via Preference | Editor | General | Auto Import | Rust. There, you can find the predefined list of exact items or catchall modules nominated for exclusion, with the possibility of defining your items from any crate.

Applying the use declaration lets the imported items bypass the exclusion settings, allowing refined control over items eligible to be shown in the completion list.

The excluded default items Borrow and BorrowMut elucidate the prime usages of this feature. Firstly, blanket implementations, especially those covering a whole set of types, may introduce the necessity to remove such extraneous elements from the completion list. Addressing this point in the scope of .borrow() and .borrow_mut() methods, we employ the heuristic approach by noticing that these methods are typically invoked on constrained type parameters and rarely used in other cases.

Secondly, tacit name clashes could introduce a change in code behavior in the same file. Again, the .borrow() method seems like a good candidate for exclusion as the Borrow:borrow clashes with RefCell::Borrow.

Both points demonstrate the unwanted ways the items in the default exclusion list may impact your code. It also expands the possibilities for practical applications of this feature.

Half-open range patterns support

At the time of writing the article (1.70.0-nightly), the half-open range patterns feature was still unstable and required a dedicated feature attribute to enable it. However, we still provided support for it. The latest Rust plugin releases provide code analysis with the capability to highlight invalid patterns, such as 1..=, 2…, …3, ..= or as errors.

Macros

During the release cycle, our team has provided a host of fixes and improvements to the nurturing of procedural macros of different kinds so that they’re on par with plain rust code outside of the macros’ scope. Let’s recap what was done exactly.

Inject language or reference inside macro body

With the recent updates comes the opportunity to mark the code block inside the macro invocation body as a specific language via the Inject language or reference intention. The IDE will handle the block as a syntactically complete language unit and provide comprehensive code assistance inside of it.

Attribute procedural macros

Type hints and hints for chained method calls

It would not be an exaggeration to say that code reference information, including type info,  allows reasoning about code quickly and exhaustively. Inlay type hints conveniently provide type information in the places across the code where type information is not given explicitly. It’s also time for this feature to appear inside procedural macros. Type hint deduction inside macros now works both for let values and intermediate type results in chained method calls.

Intention actions

Previously, intention actions, such as Specify type explicitly, were unavailable for code generated during attribute macro expansion. With the enabled experimental feature named org.rust.macros.proc.attr, everything generated on the stage of macro expansion will be available for a code analysis process, thus enabling the intention actions and inlay type hints mentioned beforehand.

Macros application for impl or trait members

Attribute macros being applied inside impl or trait blocks on a defined member might alter that member’s signature, which is crucial in code analysis. The org.rust.macros.proc.attrexperimental feature allows the Rust plugin’s engine to take into account the evaluated token stream as a resulting refreshed signature. The described preliminary application expansion contributes to providing correct type inference.

Errors highlighting

The Rust plugin employs its rich analysis tooling set for the whole range of Rust code. The latest releases enrich this powerful entity with yet another capability to use code inspections inside attribute macros to highlight errors there. In contrast to external linters like Cargo Check or Clippy, which have provided this functionality for a long time already, the Rust plugin utilizes its own techniques for rendering error messages right in the IDE code editor window.

Note that error highlighting appears only in items with successfully expanded attribute macros. Another point to keep in mind is that errors are highlighted if the annotation text range can be mapped to the macro call body.

Function-like macros

Type hints

Type hints for let values inside function-like macro call bodies are rendered in the same way as attribute macros.

Intention actions

Function-like procedural macros have previously supported almost no intention actions. Nevertheless, this has started to change from this release cycle. As of now, just like for the attribute procedural macros, another experimental feature named org.rust.ide.intentions.macros.function-like enables intention actions to work neatly in various scenarios

Conclusion

In the end, we are grateful to all the external contributors who support and help improve the plugin during this release cycle:


That was only the first part of the major highlights of the 2023.1 release. In the second part, we will look at improvements in the following areas: fresh code insight capabilities, further user experience enhancements related to Running / Debugging process, supplementary standard recognized errors and more.

We are happy to receive your feedback in the comments section below or on Twitter. Our issue tracker is there if you have a proposal or a bug to report. See you again, and thanks for staying tuned!

Your Rust team

JetBrains

The Drive to Develop

image description