Completion of Generated Code in IntelliJ Rust

Recently, I’ve been doing a lot of work with Tonic, a Rust implementation of the gRPC protocol. Like many implementations of gRPC, Tonic generates code from the protocol buffers definitions at build time using the tonic-build crate in a Cargo build script, and by default puts them in the path referred to by OUT_DIR. This has the unfortunate side effect that tooling such as IntelliJ Rust does not see the generated code for the purposes of analysis and completion - something very useful for the verbose generated protocol buffers code - unless you take some additional steps.

IntelliJ’s (excellent) Rust plugin added support for env!("OUT_DIR") when expanding include! macro calls in #4542, but disabled it again in #4573 as it makes use of a hack to determine the effective value of OUT_DIR. However, the functionality can be enabled via the “Experimental Features” dialog in IntelliJ (or, in my case, CLion).

Since I’ve never needed to look at the Experimental Features dialog in 15 years of full-time use of JetBrains Tools, this post documents the process for next time I re-build a development machine!

The dialog can be enabled using Ctrl+Alt+Shift+/ and selecting “Experimental Features”, or via the “Find Everything” dialog by searching for Experimental Features:

Experimental Features via “Find Everything”

This should provide access to the Experimental Features dialog, where you can enable the org.rust.cargo.fetch.out.dir feature to enable the support for locating OUT_DIR:

Experimental Features Dialog highlighting “org.rust.cargo.fetch.out.dir”

Once this is enabled, code analysis and completion for generated types will work:

Code Completion for Generated Protocol Buffers

Note: The macro expansion does not work using the tonic::include_proto! macro - while I haven’t verified this, it’s likely to do with the recursive nature of the macro. However, if you use include! directly as documented for tonic::include_proto!, all is well!