0

我正在尝试获取一个程序宏来打印出有关我的函数输入中的变量的信息。当我在单独的 crate 中测试宏时,我从编译器收到一个错误,即即使特征函数已明确实现,我也没有实现特征函数。

请忽略 attr 尚未返回任何内容;我正在一起构建它,但首先遇到了这个问题。

程序宏定义:

extern crate proc_macro;
use self::proc_macro::TokenStream;
use syn::{parse_macro_input, ItemFn};

#[proc_macro_attribute]
pub fn my_macro(attr: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream {
    println!("item: \"{}\"", item.to_string());
    let func = parse_macro_input!(item as ItemFn);
    let input_funcs = func.sig.inputs
            .iter()
            .map(|item| println!("{:?}", try_me(item)));

    //input_funcs
    attr
}

fn try_me(arg: &syn::FnArg) -> String {
    match arg {
        syn::FnArg::Receiver(_r) => "is receiver".to_string(),
        syn::FnArg::Typed(_p) => "is pattern type".to_string()
    }
}

测试箱:

use my_macro::{my_macro};

pub trait TestTrait {
    #[my_macro]
    fn my_func(&self, x: u8, y: String) -> u32 {
        return 0;
    }
    #[my_macro]
    fn empty_func(&mut self);
}

#[cfg(test)]
mod tests {
    // Note this useful idiom: importing names from outer (for mod tests) scope.
    use super::*;
    #[derive(Default)]
    struct MyStruct{
        pub a: u8
    }
    impl TestTrait for MyStruct{
        #[my_macro]
        fn my_func(&self, _x: u8, _y: String) -> u32 {
            return 0;
        }
        #[my_macro]
        fn empty_func(&mut self) {
            self.a = 5;
        }
    }
    #[test]
    fn test_empty_func() {
        let mut struc = MyStruct::default();
        let interface = &mut struc as &mut dyn TestTrait;
        interface.empty_func();
        assert_eq!(5, contract.a);
    }

    #[test]
    fn test_macros() {
            let mut struct = MyStruct::default();
            let interface = &mut struc as &mut dyn TestTrait;
            let zero = interface.my_func(8, "hello".to_string());
    }
}

产生错误,例如:

item: "fn my_func(&self, x: u8, y: String) -> u32 { return 0; }"
item: "fn my_func(&self, x: u8, y: String) -> u32 { return 0; }"
item: "fn empty_func(&mut self);"
item: "fn empty_func(&mut self);"
error: expected curly braces
  |
9 |     fn empty_func(&mut self);
  |                             ^

error: expected curly braces
  |
9 |     fn empty_func(&mut self);

error[E0599]: no method named `empty_func` found for mutable reference `&mut dyn TestTrait` in the current scope
   |
34 |         interface.empty_func();
   |                   ^^^^^^^^^^ method not found in `&mut dyn TestTrait`

error[E0599]: no method named `my_func` found for mutable reference `&mut dyn TestTrait` in the current scope
   |
42 |             let zero = interface.my_func(8, "hello".to_string());
   |                                  ^^^^^^^ method not found in `&mut dyn TestTrait`

如果我取消程序宏属性,则可以编译。这里发生了什么,我应该做些什么不同的事情?

4

1 回答 1

0

在 Rust Discord 中讨论后发现了这一点。给杰布罗森的道具。问题是我要回来了attr,而 attr 目前没有任何分配给它。因此,当编译器去扩展代码时,它实际上将代码缩小到......什么都没有。我基本上是在编译时删除我的代码。我不应该这样做来测试 proc 宏,而应该在使用 printlns 测试时使用 quote 并按原样引用函数。希望这对将来的某人有所帮助。

于 2020-06-10T21:04:46.830 回答