Skip to content

Pass cfgs to cargo metadata to discover correct subset of target.cfg(...) dependencies #19846

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
seritools opened this issue May 22, 2025 · 5 comments
Labels
A-cargo cargo related issues C-feature Category: feature request

Comments

@seritools
Copy link

seritools commented May 22, 2025

(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

@seritools seritools added the C-feature Category: feature request label May 22, 2025
@seritools seritools changed the title Cfgs are not passed to cargo metadata, target.cfg(...) dependencies not discovered Pass cfgs to cargo metadata to discover correct subset of target.cfg(...) dependencies May 22, 2025
@Veykril
Copy link
Member

Veykril commented May 22, 2025

This does sound like a hole in the cargo metadata clip API to me, so this probably be raised on the cargo repo

@seritools
Copy link
Author

Thanks for confirming, created the respective issue here: rust-lang/cargo#15576

@seritools
Copy link
Author

seritools commented May 23, 2025

Thinking about this a bit more and reading @epage's comment over on the cargo issue -- I think this is purely a rust-analyzer issue: In the end, it introduces a "side channel" for cfgs that the rest of the toolchain doesn't know about. I feel the naming of rust-analyzer.cargo.cfgs isn't ideal, as it seems like it would configure cargo (like extraEnv does), but is used purely within rust-analyzer if I understand correctly.

In the work project we've decided to just also set the corresponding RUSTFLAGS via rust-analyzer.cargo.extraEnv, which causes them to also get passed to cargo metadata, resolving the issue.

Maybe it's just a documentation issue for rust-analyzer.cargo.cfgs in the end?

@kupiakos
Copy link

kupiakos commented Jun 5, 2025

it seems like it would configure cargo (like extraEnv does), but is used purely within rust-analyzer

@seritools I've filed #19926 about this - I agree it's a confusing situation.

@Veykril
Copy link
Member

Veykril commented Jun 5, 2025

We should definitely document this at the very least yes. I am not sure we can modify RUSTFLAGS though, I can see this causing a lot of (confusing) issues for users

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-cargo cargo related issues C-feature Category: feature request
Projects
None yet
Development

No branches or pull requests

3 participants