Skip to content
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

Testing a proc macro may build with the wrong crates with -Zfeatures=all #8563

Closed
alexcrichton opened this issue Jul 29, 2020 · 1 comment · Fixed by #8742
Closed

Testing a proc macro may build with the wrong crates with -Zfeatures=all #8563

alexcrichton opened this issue Jul 29, 2020 · 1 comment · Fixed by #8742
Labels
A-features2 Area: issues specifically related to the v2 feature resolver

Comments

@alexcrichton
Copy link
Member

This is unfortunately a bit of a complicated issue. This came up when we tested out using -Zfeatures=all on the wasmtime repository where we got an error that looked like:

error[E0277]: the trait bound `wiggle_generate::Config: syn::parse::Parse` is not satisfied
  --> crates/wiggle/macro/src/lib.rs:9:33
   |
9  |     parse_macro_input!(args2 as wiggle_generate::Config);
   |                                 ^^^^^^^^^^^^^^^^^^^^^^^ the trait `syn::parse::Parse` is not implemented for `wiggle_generate::Config`
   |
  ::: /home/alex/.cargo/registry/src/github.com-1ecc6299db9ec823/syn-1.0.34/src/parse_macro_input.rs:93:17
   |
93 | pub fn parse<T: ParseMacroInput>(token_stream: TokenStream) -> Result<T> {
   |                 --------------- required by this bound in `syn::parse_macro_input::parse`
   |
help: trait impl with same name found
  --> /home/alex/code/wasmtime/crates/wiggle/generate/src/lib.rs:3:1
   |
3  | / impl syn::parse::Parse for Config {
4  | |     fn parse(_: &syn::parse::ParseBuffer<'_>) -> syn::Result<Self> {
5  | |         panic!()
6  | |     }
7  | | }
   | |_^
   = note: perhaps two different versions of crate `syn` are being used?
   = note: required because of the requirements on the impl of `syn::parse_macro_input::ParseMacroInput` for `wiggle_generate::Config`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: could not compile `wiggle-macro`.

this is perplexing because it looks like Cargo's compiling something with the wrong version of syn, since there's two versions of syn in play and that shouldn't happen.

I was able to reduce this to a test:

#[cargo_test]
fn test_proc_macro() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
                [package]
                name = "runtime"
                version = "0.1.0"
                [dependencies]
                the-macro = { path = "the-macro", features = ['a'] }
                [build-dependencies]
                shared = { path = "shared", features = ['b'] }
            "#,
        )
        .file("src/lib.rs", "")
        .file(
            "the-macro/Cargo.toml",
            r#"
                [package]
                name = "the-macro"
                version = "0.1.0"
                [lib]
                proc-macro = true
                test = false
                [dependencies]
                the-macro-support = { path = "../the-macro-support" }
                shared = { path = "../shared" }
                [dev-dependencies]
                runtime = { path = ".." }
                [features]
                a = []
            "#,
        )
        .file(
            "the-macro/src/lib.rs",
            "
                fn _test() {
                    the_macro_support::foo(shared::Foo);
                }
            ",
        )
        .file(
            "the-macro-support/Cargo.toml",
            r#"
                [package]
                name = "the-macro-support"
                version = "0.1.0"
                [dependencies]
                shared = { path = "../shared" }
            "#,
        )
        .file(
            "the-macro-support/src/lib.rs",
            "
                pub fn foo(_: shared::Foo) {}
            ",
        )
        .file(
            "shared/Cargo.toml",
            r#"
                [package]
                name = "shared"
                version = "0.1.0"
                [features]
                b = []
            "#,
        )
        .file("shared/src/lib.rs", "pub struct Foo;")
        .build();
    p.cargo("test -Zfeatures=all --manifest-path the-macro/Cargo.toml")
        .masquerade_as_nightly_cargo()
        .run();
}

which yields:

---- features2::test_proc_macro stdout ----
running `/home/alex/code/cargo/target/debug/cargo test -Zfeatures=all --manifest-path the-macro/Cargo.toml`
thread 'features2::test_proc_macro' panicked at '
Expected: execs
    but: exited with exit code: 101
--- stdout

--- stderr
   Compiling shared v0.1.0 (/home/alex/code/cargo/target/cit/t0/foo/shared)
   Compiling the-macro-support v0.1.0 (/home/alex/code/cargo/target/cit/t0/foo/the-macro-support)
   Compiling the-macro v0.1.0 (/home/alex/code/cargo/target/cit/t0/foo/the-macro)
error[E0308]: mismatched types
 --> src/lib.rs:3:44
  |
3 |                     the_macro_support::foo(shared::Foo);
  |                                            ^^^^^^^^^^^ expected struct `shared::Foo`, found a different struct `shared::Foo`
  |
  = note: perhaps two different versions of crate `shared` are being used?

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
error: could not compile `the-macro`.

To learn more, run the command again with --verbose.
warning: build failed, waiting for other jobs to finish...
error: build failed
', crates/cargo-test-support/src/lib.rs:832:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    features2::test_proc_macro

cc @ehuss, you're likely interested in this!

@alexcrichton alexcrichton added the A-features2 Area: issues specifically related to the v2 feature resolver label Jul 29, 2020
@ehuss
Copy link
Contributor

ehuss commented Jul 31, 2020

This is a tricky one, somewhat the confluence of three different issues. The following is mostly notes to myself.

The primary issue is probably #8549. the-macro-support needs to be built twice (once for host, once without), but due to unit unification (without --target), it is only built once because the only difference is what it links to (shared with no features, and shared with feature B).

Another issue is this line. This forces proc-macros to be built for-host, even if it is a test. So the fix to above doesn't completely solve the issue.

Another issue is possibly #8312. proc-macros have some unusual requirements (like this). Not sure how this fits in the picture. There is some wonkiness around cargo test for proc-macros.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-features2 Area: issues specifically related to the v2 feature resolver
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants