如何在同一个 crate 中使用由另一个宏定义的宏?
Posted
技术标签:
【中文标题】如何在同一个 crate 中使用由另一个宏定义的宏?【英文标题】:How to use a macro which is defined by another macro in the same crate? 【发布时间】:2019-05-27 02:03:17 【问题描述】:我正在定义一个像这样定义其他宏的宏:
macros.rs
#[macro_export]
macro_rules! m1
() =>
#[macro_export]
macro_rules! m2
() =>
m1!();
m2!(); // no problem;
我可以通过use crate_name::macros::*
在另一个板条箱中使用m2!
,我可以在macros.rs
中使用m2!
,但我不知道如何在同一个板条箱中的文件中使用m2!
。
lib.rs
#[macro_use]
pub mod macros;
pub mod test;
pub mod test2;
test.rs(与 macros.rs 在同一个 crate 中)
use crate::m1; // no problem
use crate::m2; // ERROR: macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths
m1!(); // no problem
m2!(); // error, no m2
test2.rs
use crate::*;
m2!(); // this works, but I don't really want to use crate::*
examples/yo.rs
use crate_name::m2;
m2!(); // no problem
在同一个 crate 的其他文件中使用 m2
宏的正确方法是什么?我正在使用 Rust 1.31.1。
【问题讨论】:
【参考方案1】:阅读并遵循编译器的说明:
error[E0659]: `m2` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
--> src/lib.rs:22:5
|
22 | m2!();
| ^^ ambiguous name
|
note: `m2` could refer to the macro defined here
--> src/lib.rs:7:13
|
7 | / macro_rules! m2
8 | | () => ;
9 | |
| |_____________^
...
21 | m1!();
| ------ in this macro invocation
note: `m2` could also refer to the macro defined here
--> src/lib.rs:7:13
|
7 | / macro_rules! m2
8 | | () => ;
9 | |
| |_____________^
...
13 | m1!();
| ------ in this macro invocation
error: a macro named `m2` has already been exported
--> src/lib.rs:7:13
|
7 | / macro_rules! m2
8 | | () => ;
9 | |
| |_____________^ `m2` already exported
...
21 | m1!();
| ------ in this macro invocation
|
= note: #[deny(duplicate_macro_exports)] on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
= note: for more information, see issue #35896 <https://github.com/rust-lang/rust/issues/35896>
note: previous macro export is now shadowed
--> src/lib.rs:7:13
|
7 | / macro_rules! m2
8 | | () => ;
9 | |
| |_____________^
...
13 | m1!();
| ------ in this macro invocation
error: macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths
--> src/lib.rs:19:9
|
19 | use crate::m2;
| ^^^^^^^^^
|
= note: #[deny(macro_expanded_macro_exports_accessed_by_absolute_paths)] on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #52234 <https://github.com/rust-lang/rust/issues/52234>
note: the macro is defined here
--> src/lib.rs:7:13
|
7 | / macro_rules! m2
8 | | () => ;
9 | |
| |_____________^
...
21 | m1!();
| ------ in this macro invocation
具体来说:
错误:当前 crate 中的宏扩展
macro_export
宏不能被绝对路径引用
应用:
-
不要导入宏;没必要。
请勿拨打
m1
;这样做会创建第二个m2
。
test.rs
// use crate::m1;
// use crate::m2;
// m1!();
m2!();
【讨论】:
谢谢,很清楚,彻底解决了问题。以上是关于如何在同一个 crate 中使用由另一个宏定义的宏?的主要内容,如果未能解决你的问题,请参考以下文章
Rust 1.7.0 macro宏的复用 #[macro_use]的使用方法