Pre-RFC: configure default used features in config.toml , make rust-analyzer and cargo use it as default

It is an idea I have this afternoon..

Problem

It is annoying for we lsp user to switch the features we used in a rust project. Rust-analyer needed to be passed with the feature to selected, then it can finally enable the feature, and highlight the code related. In vscode, we can edit .vscode/settings.json, but even that it is annoying enough. Why when I switch features, I need to rewrite the config file.

Idea

I thought about what meson build and cmake do. In the build system of mesonbuild or cmake, they have a action called configure(I got mistaken in last edition, call it precompile). like

meson setup build -D ENABLE_A=ON

and it write config to build folder, next time it do

meson compile -C build

it will use the feature to compile,

compile to cargo, every time I need to pass --feature to tell it which features to use.

And inducing the flow of precompile to config the file allow clangd to know which option to open, this make every time, I just to reconfig the build option, then I will switch to other features, and lsp know it. I do not need to rewrite the config in project, to tell lsp to enable the features

Maybe solution

(second edition, helped by mathstuf and Nemo157)

maybe we can induce some option for cargo , like config the .cargo/config.toml, add something like

[profile.dev.package.<name>]
default-features = ["a", "b"]

this step make cargo remember the feature it used, next time I just need to run

cargo build

Then we do not to pass --feature to it again and again, and rust-analyer can use the option to do completion and highlight, no need to use extra .vscode/settings.json or other configure file for some other editor.

and because it write something to target folder, then rust-analyzer can read it , then it will know it should enable which feature and disable others

This is the first time I make a pre-rfc. what do you think about the idea?

1 Like

One idea might be to have features enabled by profiles

[profile.dev]
all-features = true

This would allow configuring them both in the committed Cargo.toml to have a default-set used for contributors (avoiding the need for hacks like #[cfg(not(feature = "_tests"))] compile_error!("please test with --all-features");) and overriding them in an uncommitted .cargo/config.toml if you want to change them locally. Having it at the profile level would also allow for enabling things like high-performance features in profile.release or extra-debug-checks in profile.dev.

5 Likes

(I'm a CMake developer.)

This is usually called the "configure" step, named after the autoconf entrypoint. It basically gathers information for the build to use so that users don't need to remember to type it in all the time.

It sounds like profiles are the way to go as long as there's a way to set "everything" that might be wanted there (not just features, but also things like --tests and --frozen) and a way to select a profile ambiently (via an environment variable or .cargo/ file) that is picked up automatically.

1 Like

I think you are right. Put it in config.toml is more reasonable.

https://doc.rust-lang.org/cargo/reference/config.html

Maybe this rfc can become add keywords to this file?

like such kind?

[profile.dev.package.<name>]
default-features = []

and both cargo and rust-analyer can read it, seems good.

Sometimes when editing code with cfgs I need to work on both cfg(feature = "foo") and cfg(not(feature = "foo")), or two different targets.

Therefore the way I'd like to see this work is to have it built into RA — to be able to click on a cfg and ask "change settings so this is active". This seems like a better workflow than to have to set up a custom profile for each situation, then activate it.

5 Likes

I agree, but I would like to see this go a step further: what if I want to edit OS specific code, even though I may not have access to that code outside of github CI (this has happened for both Windows and Mac OS X, I use Linux myself).

Not sure how feasible that would be, the OS specific code may depend on OS specific system headers and libraries that are not possible to redistribute. I believe this is particularly a problem for Mac OS X, for Windows we can at least cross compile with the gnu toolchain.

All is not lost however, as this would also be useful embedded, where I might want to switch between targeting for example a specific ESP32C board and Pi Pico (at least for libraries, not realistic for actual final applications).