Unexpected compilation error with procedural macros

I have the following project and get an unexpected compiler error. Inside the function foo in src/lib.rs, the generic type of Vec::new() cannot be inferred.

I do not get the compiler error if I do one of:

  • remove the call to #[::bug_macro::bug_macro] in src/lib.rs. Note that this macro does not do to any ast-transformations
  • remove the call to json::parse in bug-macro/src/lib.rs. Note that this is an implementation detail of a private function that is never called
  • I use the bug_macro directly from the bug-macro-codegen crate, even if it contains a call to json::parse.

Have I uncovered some compiler error?

I tried to minify the error and got following 3-crate Project:
Cargo.toml

[package]
name = "bug"
version = "0.1.0"
edition = "2018"

[dependencies]
bug-macro = {path = "bug-macro"}

src/lib.rs

#[::bug_macro::bug_macro]
pub fn bar() {}

pub fn foo() {
    let sum = Vec::new();
    b"" == &sum[..];
}

bug-macro/Cargo.toml

[package]
name = "bug-macro"
version = "0.2.0"
edition = "2018"

[dependencies]
bug-macro-codegen = { path = "../bug-macro-codegen" }
json = "0.11"

bug-macro/src/lib.rs

pub use bug_macro_codegen::bug_macro;
fn jkl() {json::parse("");}

bug-macro-codegen/Cargo.toml:

[package]
name = "bug-macro-codegen"
version = "0.2.0"
edition = "2018"

[lib]
proc_macro = true

bug-macro-codegen/src/lib.rs

extern crate proc_macro;

#[proc_macro_attribute]
pub fn bug_macro(
    _attr: proc_macro::TokenStream,
    input: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
    input
}

What is the exact error?

The error is: (using cargo 1.40.0-nightly (5da4b4d47 2019-10-28), rustc 1.40.0-nightly (b520af6fd 2019-11-03))

error[E0282]: type annotations needed for `std::vec::Vec<T>`
 --> src/lib.rs:5:15
  |
5 |     let sum = Vec::new();
  |         ---   ^^^^^^^^ cannot infer type for `T`
  |         |
  |         consider giving `sum` the explicit type `std::vec::Vec<T>`, where the type parameter `T` is specified

However, the snippet responsible for the code (line 5 and function foo in general) does not trigger this error by itself, since this compiles fine:

pub fn foo() {
    let sum = Vec::new();
    b"" == &sum[..];
}

I do not understand how the other crates and proc-macro affects this piece of code.

I can reproduce this, and yes, it looks like a compiler bug to me. One next step to tracking it down might be to reduce the json crate in order to get a truly minimal test case.

1 Like

I am really glad this is not only me. I will try to track it down in json. We will see how far I can get.

I found the underlying issue: playground It had nothing to do with the macro-system.

The json crate defined some type Number and an instance PartialEq<Number> for u8 for it. Due to trait coherency rules, the trait came into scope and made the code fail to compile.

3 Likes