【问题标题】:How to use a macro which is defined by another macro in the same crate?如何在同一个 crate 中使用由另一个宏定义的宏?
【发布时间】:2019-05-27 02:03:17
【问题描述】:

我正在定义一个像这样定义其他宏的宏:

ma​​cros.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。

【问题讨论】:

    标签: macros rust


    【解决方案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 宏不能被绝对路径引用

    应用:

    1. 不要导入宏;没必要。
    2. 请勿拨打m1;这样做会创建第二个m2

    test.rs

    // use crate::m1;
    // use crate::m2; 
    
    // m1!();
    m2!();
    

    【讨论】:

    • 谢谢,很清楚,彻底解决了问题。
    猜你喜欢
    • 1970-01-01
    • 2013-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多