Feature Unification Problem with Proc-Macros and Dev-Dependencies in a Cargo Workspace
โ Rust ๐ 2025-09-10 ๐ค surdeus ๐๏ธ 9In this repo, a simple model of a workspace with crates and features is described to demonstrate an issue:
root (workspace)
โโโ parser
โโโ grammar (proc-macro)
โโโ parser
[dev-dependencies]
โโโ root
โโโ grammar
โโโ parser
[dev-dependencies]
โโโ root
The "logs" feature is intended both for displaying logs in tests when testing the parser::parse() function, and for exposing this functionality to users, so they can also output logs in their own parser::parse() tests.
We can think of grammar::tests::grammar_test as a user of parser::parse() when testing:
#[test]
fn grammar_test() {
// Testing code from grammar!
root::parser::parse();
}
// Let's imagine that grammar generates some code.
root::grammar::grammar!();
Imagine that the code generated by grammar! can also be tested with parser::parse(), and the grammar developer wants to see logs.
They can run $ cargo test -p grammar --test test grammar_test -- --show-output and get:
[parser/src/lib.rs:2:8] cfg!(feature = "logs") = true
parsing...
Finished `test` profile [unoptimized + debuginfo] target(s) in 0.01s
Running tests/test.rs (target/debug/deps/test-0e531f70eaa559ba)
running 1 test
test grammar_test ... ok
successes:
---- grammar_test stdout ----
[parser/src/lib.rs:2:8] cfg!(feature = "logs") = true
parsing...
successes:
grammar_test
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
โ the logs from grammar_test are displayed correctly, but there is a problem: grammar! internally uses parser::parse(), and during build it prints logs to the console โ those can be seen at the very beginning. It happens as if the "logs" feature was enabled for parser in grammarโs dependencies, but thatโs not the case! The issue lies in feature unification.
I read about Feature resolver version 2, and it seems like this could solve the problem. What caught my eye in particular was:
The exact situations are described in the resolver chapter, but in short, it avoids unifying in these situations:
...
- Build-dependencies and proc-macros do not share features with normal dependencies.
...
But I canโt get it to work.
1 post - 1 participant
๐ท๏ธ Rust_feed