首页 > 解决方案 > 在 Rust 宏中,如何跟随符号获取另一个函数定义的令牌流?

问题描述

一个宏修饰的函数调用另一个函数,如何在宏中获取被调用函数的令牌流?

装饰功能:

#[follow]
fn caller(){
  return callee();
}

被调用者:

fn callee(){
  ... // some implementation
}

宏:

#[proc_macro_attribute]
pub fn follow(_metadata: TokenStream, _input: TokenStream) -> TokenStream {
   // how to get callee's token stream here? 
}

标签: rustmetaprogrammingrust-macrosrust-proc-macros

解决方案


宏只能访问作为输入提供的令牌,因此在一般情况下这通常是不可能的。

如果您准备将代码重组为模块,则可以编写一组可以像这样使用的宏:

#[exec_follow]
mod my_mod {
    #[follow]
    fn caller(){
        return callee();
    }

    fn callee() {
        ... // some implementation
    }
}

外部宏exec_follow将接收整个模块作为输入并重写对follow宏的调用以提供所需的信息。例如,exec_follow可以输出这个:

mod my_mod {
    #[follow(source = r"mod my_mod {
    #[follow]
    fn caller(){
        return callee();
    }

    fn callee() {
        ... // some implementation
    }
}")]
    fn caller() {
        return callee();
    }

    fn callee() {
        ... // some implementation
    }
}

这只有在所有项目都在同一个模块中声明时才有效,该模块需要是当前模块的子模块。

添加对内部属性作为宏的支持是一个未解决的问题,但它在稳定的 Rust 中尚不可用。这将使您可以#![exec_follow]在文件顶部使用,而不是添加嵌套模块。


推荐阅读