0

我有一个无法编译的小型复制项目。该项目可以在这里下载: https ://github.com/Jasperav/proc_macro_collision 。错误是:

error[E0659]: `proc_macro_call` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)

我在项目中有 3 个库和 1 个可执行文件:

  • Lib 1 - 解析器 - 解析 proc 宏调用
  • Lib 2 - proc_two - 将文字字符串作为 proc 宏调用返回
  • Lib 3 - proc_one - 将宏转发到 proc_two(尽管它不依赖于 proc_two)。这就像 proc_two 也是一个 proc 宏。

proc_one 的相关代码:

#[proc_macro_hack]
pub fn one(input: TokenStream) -> TokenStream {
    let parse = parse_macro_input!(input as Parser);
    let r = parse.lit;

    let x = quote! {
        two!(#r) // This is the problem I guess...
    };

    x.into()
}
  • 可执行文件:调用 proc_one(给出编译错误)。

相关代码:

use proc_macro_hack::proc_macro_hack;
extern crate proc_one;
extern crate proc_two;

#[proc_macro_hack]
use proc_one::one;
#[proc_macro_hack]
use proc_two::two;

fn main() {
    let hi: &'static str = one!("hi");

    assert_eq!("hi", hi);
}

我不明白为什么可执行文件中的调用不明确,lib 2 和 3 不相互依赖。这是完整的错误:

error[E0659]: `proc_macro_call` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
  --> src\main.rs:10:1
   |
10 | #[proc_macro_hack]
   | ^^^^^^^^^^^^^^^^^^ ambiguous name
...
14 |     let hi: &'static str = one!("hi");
   |                            ---------- in this macro invocation
   |
note: `proc_macro_call` could refer to the macro defined here
  --> src\main.rs:11:15
   |
11 | use proc_two::two;
   |               ^^^
...
14 |     let hi: &'static str = one!("hi");
   |                            ---------- in this macro invocation
note: `proc_macro_call` could also refer to the macro defined here
  --> src\main.rs:9:15
   |
9  | use proc_one::one;
   |               ^^^
...
14 |     let hi: &'static str = one!("hi");
   |                            ---------- in this macro invocation
   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
4

1 回答 1

1

根据proc_macro_hack 文档 ,不支持嵌套调用

默认情况下,不支持嵌套调用,即 proc-macro-hack 宏调用发出的代码不能包含对同一 proc-macro-hack 宏的递归调用,也不能包含对任何其他 proc-macro-hack 宏的调用。如果您需要对嵌套调用的支持,请使用 proc-macro-nested。

因此,您标记的代码是真正的问题:

let x = quote! {
    two!(#r) // This is the problem
};

并且有一个建议查看proc-macro-nested “如果您需要支持嵌套调用”。

于 2020-05-18T13:24:17.907 回答