Closed
Description
The quote_*
macros stringify everything, which loses vital information.
// gensym.rs
#![feature(plugin_registrar, managed_boxes, quote)]
#![crate_type = "dylib"]
extern crate syntax;
extern crate rustc;
use syntax::ast;
use syntax::codemap::{Span};
use syntax::ext::base;
use syntax::ext::base::{ExtCtxt, MacExpr};
use syntax::ext::build::AstBuilder;
use syntax::parse::token;
use rustc::plugin::Registry;
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
reg.register_macro("test_quote", expand_syntax_ext);
}
pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, _: &[ast::TokenTree]) -> Box<base::MacResult> {
// expand to `{ let foo = true; foo }`, with a gensym'd foo.
let ident = token::gensym_ident("foo");
let decl = quote_stmt!(&mut *cx, let $ident = true;);
let result = cx.expr_block(cx.block(sp, vec![decl], Some(cx.expr_ident(sp, ident))));
println!("{}", result);
MacExpr::new(result)
}
// test_gensym.rs
#![feature(phase)]
#[phase(plugin)] extern crate gensym;
fn main() {
let a = test_quote!();
}
[...]
test_gensym.rs:6:13: 6:27 error: unresolved name `foo`.
test_gensym.rs:6 let a = test_quote!();
^~~~~~~~~~~~~~
test_gensym.rs:1:1: 7:1 note: in expansion of test_quote!
test_gensym.rs:6:13: 6:27 note: expansion site
error: aborting due to previous error
Beautified/trimmed version of the output of the println!
Expr {
node: ExprBlock(Block {
view_items: [],
stmts: [Spanned {
node: StmtDecl(Spanned {
node: DeclLocal(Local {
ty: Ty {
node: TyInfer,
span: Span {
lo: BytePos(7677),
hi: BytePos(7677),
expn_info: None
}
},
pat: Pat {
node: PatIdent(BindByValue(MutImmutable), Spanned {
node: "foo" (269),
span: Span {
lo: BytePos(7677),
hi: BytePos(7680),
expn_info: None
}
}, None),
span: Span {
lo: BytePos(7677),
hi: BytePos(7680),
expn_info: None
}
},
init: Some(Expr {
node: ExprLit(Spanned {
node: LitBool(true),
span: Span {
lo: BytePos(83),
hi: BytePos(97),
expn_info: None
}
}),
span: Span {
lo: BytePos(83),
hi: BytePos(97),
expn_info: None
}
}),
span: Span {
lo: BytePos(7677),
hi: BytePos(97),
expn_info: None
},
source: LocalLet
}),
}, 4294967295),
}],
expr: Some(Expr {
node: ExprPath(Path {
global: false,
segments: [PathSegment {
identifier: "foo" (268)# 0,
lifetimes: [],
types: OwnedSlice {
{}
}
}]
}),
}),
rules: DefaultBlock,
}),
}
Of particular attention is the difference in Name
between node: "foo" (269)
identifier: "foo" (268)# 0,
, and also the 7677
etc. numbers in the spans inside theDeclLocal
.