(This is somewhere between a bug report and a feature request)
At work we've got a setup where various cfgs are being set depending on outside configuration. For rust-analyzer, we set these via the rust-analyzer.cargo.cfgs setting:
{
"rust-analyzer.cargo.cfgs": ["my_custom_cfg=foobar"],
}
This works fine as long as all cfg checks remain only in Rust code. We did start, however, to use target dependencies based on these cfgs as well:
[target.'cfg(my_custom_cfg = "foobar")'.dependencies]
bar = { workspace = true }
Sadly, rust-analyzer doesn't recognize and load these dependencies, and the relevant imports and code lose all LSP benefits.
A minimal reproduction repository can be found here: https://github.com/seritools/cfg-dependencies-repro
I've looked into what's happening and traced it back to the cargo metadata call in CargoWorkspace::fetch_metadata_: Generally, rust-analyzer passes the --filter-platform argument to cargo metadata, to filter out dependencies for other targets. It seems that --filter-platform causes cargo metadata to evaluate all target.'cfg(...)' configurations, including those using custom cfgs.
Finally, the problem is that cfgs set via the rust-analyzer.cargo.cfgs setting are not passed to cargo metadata, meaning that the returned metadata becomes out of sync with the expected config.
To confirm that that is the problem (and as a hacky proof-of-concept solution) I patched rust-analyzer to inject the specified cfgs via CARGO_ENCODED_RUSTFLAGS: master...seritools:rust-analyzer:extra-cfgs-for-cargo-metadata
I've confirmed that this allows cargo metadata to return the correct dependency tree. This proof of concept solution is of course not sane for general use (because of how it breaks RUSTFLAGS usage), but I hope it shows the issue and and idea for resolution.
Personally, I couldn't think of a way to implement this sanely that doesn't also involve extending cargo metadata -- something akin to --filter-cfg to pass in extra cfgs. What do you think? If that seems reasonable, I'll also create an issue in the cargo repository and link it to this one. Created the respective cargo issue: rust-lang/cargo#15576
(This is somewhere between a bug report and a feature request)
At work we've got a setup where various
cfgs are being set depending on outside configuration. For rust-analyzer, we set these via therust-analyzer.cargo.cfgssetting:{ "rust-analyzer.cargo.cfgs": ["my_custom_cfg=foobar"], }This works fine as long as all
cfgchecks remain only in Rust code. We did start, however, to use target dependencies based on thesecfgs as well:Sadly, rust-analyzer doesn't recognize and load these dependencies, and the relevant imports and code lose all LSP benefits.
A minimal reproduction repository can be found here: https://github.com/seritools/cfg-dependencies-repro
I've looked into what's happening and traced it back to the
cargo metadatacall inCargoWorkspace::fetch_metadata_: Generally, rust-analyzer passes the--filter-platformargument tocargo metadata, to filter out dependencies for other targets. It seems that--filter-platformcausescargo metadatato evaluate alltarget.'cfg(...)'configurations, including those using customcfgs.Finally, the problem is that
cfgs set via therust-analyzer.cargo.cfgssetting are not passed tocargo metadata, meaning that the returned metadata becomes out of sync with the expected config.To confirm that that is the problem (and as a hacky proof-of-concept solution) I patched rust-analyzer to inject the specified
cfgs viaCARGO_ENCODED_RUSTFLAGS: master...seritools:rust-analyzer:extra-cfgs-for-cargo-metadataI've confirmed that this allows
cargo metadatato return the correct dependency tree. This proof of concept solution is of course not sane for general use (because of how it breaksRUSTFLAGSusage), but I hope it shows the issue and and idea for resolution.Personally, I couldn't think of a way to implement this sanely that doesn't also involve extending
cargo metadata-- something akin to--filter-cfgto pass in extra cfgs. What do you think?If that seems reasonable, I'll also create an issue in the cargo repository and link it to this one.Created the respective cargo issue: rust-lang/cargo#15576