如何在Rust过程宏中创建多个项目?

时间:2014-08-04 04:21:04

标签: macros rust

我正在尝试创建一个宏,当像这样使用时:

foo!()

扩展为两个项目,静态项目和功能。像这样:

static x: uint = 5;

fn bar() -> uint { x + 1 }

我已经指出MacResult的{​​{1}}方法支持这一点,所以我只需要创建一个正确实现它的类型。我这样做了:

make_items

我试图使用struct MacItems { items: Vec<::std::gc::Gc<Item>>, } impl MacResult for MacItems { fn make_def(&self) -> Option<::syntax::ext::base::MacroDef> { None } fn make_expr(&self) -> Option<::std::gc::Gc<ast::Expr>> { None } fn make_pat(&self) -> Option<::std::gc::Gc<ast::Pat>> { None } fn make_stmt(&self) -> Option<::std::gc::Gc<ast::Stmt>> { None } fn make_items(&self) -> Option<::syntax::util::small_vector::SmallVector<::std::gc::Gc<Item>>> { Some(::syntax::util::small_vector::SmallVector::many(self.items.clone())) } } 宏,但这个宏显然会移动quote_item!,因此无法连续两次使用它。这是我的代码:

ExtCtxt

这是错误:

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_macro("foo", expand);
}

fn expand(cx: &mut ExtCtxt, sp: codemap::Span, _: &[ast::TokenTree]) -> Box<MacResult> {
    let mut v = vec!();

    v.push( quote_item!(cx, static x: uint = 5;).unwrap() );
    v.push( quote_item!(cx, fn bar() -> uint { x + 1 }).unwrap() );

    box MacItems { items: v } as Box<MacResult>
}

我怎样才能做到这一点?我尝试使用test.rs:37:13: 37:57 error: use of moved value: `cx` test.rs:37 v.push( quote_item!(cx, fn bar() -> uint { x + 1 }).unwrap() ); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ note: in expansion of quote_item! test.rs:37:13: 37:57 note: expansion site test.rs:36:13: 36:50 note: `cx` moved here because it has type `&mut syntax::ext::base::ExtCtxt<'_>`, which is moved by default (use `ref` to override) test.rs:36 v.push( quote_item!(cx, static x: uint = 5;).unwrap() ); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ note: in expansion of quote_item! test.rs:36:13: 36:50 note: expansion site error: aborting due to previous error 创建静态项,但我无法确定AstBuilder::item_static的哪个变体对应Ty_。 (这只是一个玩具示例,我的真实静态声明是uint,所以我需要构建该项目。)

我这样做完全错了吗?如何实现这一目标?

1 个答案:

答案 0 :(得分:3)

您需要手动将cx重新导出为临时&mut ExtCtxt。编译器通常可以自动插入重新生成,但quote_*宏不会扩展到适用于此的内容。

即,

quote_item!(&mut *cx, ...)