在其他 proc 宏中调用 proc 宏
Call proc macro inside other proc macro
我有一个无法编译的小型复制项目。该项目可以在这里下载: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 个可执行文件:
- 库 1 - 解析器 - 解析 proc 宏调用
- Lib 2 - proc_two - returns 作为 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)
根据 proc_macro_hack
documentation 不支持嵌套调用:
By default, nested invocations are not supported i.e. the code emitted by a proc-macro-hack macro invocation cannot contain recursive calls to the same proc-macro-hack macro nor calls to any other proc-macro-hack macros. Use proc-macro-nested if you require support for nested invocations.
因此您标记的代码是真正的问题:
let x = quote! {
two!(#r) // This is the problem
};
还有一个建议可以看看proc-macro-nested"if you require support for nested invocations"。
我有一个无法编译的小型复制项目。该项目可以在这里下载: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 个可执行文件:
- 库 1 - 解析器 - 解析 proc 宏调用
- Lib 2 - proc_two - returns 作为 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)
根据 proc_macro_hack
documentation 不支持嵌套调用:
By default, nested invocations are not supported i.e. the code emitted by a proc-macro-hack macro invocation cannot contain recursive calls to the same proc-macro-hack macro nor calls to any other proc-macro-hack macros. Use proc-macro-nested if you require support for nested invocations.
因此您标记的代码是真正的问题:
let x = quote! {
two!(#r) // This is the problem
};
还有一个建议可以看看proc-macro-nested"if you require support for nested invocations"。