簡體   English   中英

如何在Rust過程宏中創建多個項目?

[英]How can I create multiple items in a Rust procedural macro?

我正在嘗試創建一個宏,當像這樣使用時:

foo!()

擴展為兩個項目,靜態項目和功能。 像這樣的東西:

static x: uint = 5;

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

我已經向我指出, MacResultmake_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 (這只是一個玩具示例,我真正的靜態聲明是&'static str ,所以我需要構建該項目)。

我這樣做完全錯了嗎? 怎么能實現這一目標?

您需要手動將cx重新借用到臨時&mut ExtCtxt 編譯器通常可以自動插入reborrows,但quote_*宏不會擴展為適合此的東西。

那是,

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM