Feature Unification Problem with Proc-Macros and Dev-Dependencies in a Cargo Workspace

โš“ Rust    ๐Ÿ“… 2025-09-10    ๐Ÿ‘ค surdeus    ๐Ÿ‘๏ธ 9      

surdeus

Warning

This post was published 63 days ago. The information described in this article may have changed.

In 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

Read full topic

๐Ÿท๏ธ Rust_feed