提交 9fb11fe9 编写于 作者: J Jared Roesch

Extend macro machinery to expand macros in types

Reapplied the changes from https://github.com/freebroccolo/rust/commit/7aafe24139abc2d1f302bbb166bcaa006f12cf4d
to a clean branch of master
上级 edca562c
......@@ -290,6 +290,10 @@ fn make_pat(self: Box<Self>) -> Option<P<ast::Pat>> {
fn make_stmts(self: Box<Self>) -> Option<SmallVector<P<ast::Stmt>>> {
make_stmts_default!(self)
}
fn make_ty(self: Box<Self>) -> Option<P<ast::Ty>> {
None
}
}
macro_rules! make_MacEager {
......@@ -322,6 +326,7 @@ pub fn $fld(v: $t) -> Box<MacResult> {
items: SmallVector<P<ast::Item>>,
impl_items: SmallVector<P<ast::ImplItem>>,
stmts: SmallVector<P<ast::Stmt>>,
ty: P<ast::Ty>,
}
impl MacResult for MacEager {
......@@ -359,6 +364,10 @@ fn make_pat(self: Box<Self>) -> Option<P<ast::Pat>> {
}
None
}
fn make_ty(self: Box<Self>) -> Option<P<ast::Ty>> {
self.ty
}
}
/// Fill-in macro expansion result, to allow compilation to continue
......@@ -405,6 +414,12 @@ pub fn raw_pat(sp: Span) -> ast::Pat {
}
}
pub fn raw_ty(sp: Span) -> P<ast::Ty> {
P(ast::Ty {
id: ast:DUMMY_NODE_ID,
node: ast::TyInfer,
span: sp
})
}
impl MacResult for DummyResult {
......
......@@ -1552,6 +1552,35 @@ fn expand_and_rename_method(sig: ast::MethodSig, body: P<ast::Block>,
}, rewritten_body)
}
pub fn expand_type(t: P<ast::Ty>, fld: &mut MacroExpander) -> P<ast::Ty> {
let t = match t.node.clone() {
ast::Ty_::TyMac(mac) => {
let expanded_ty = match expand_mac_invoc(mac, t.span,
|r| r.make_ty(),
mark_ty,
fld) {
Some(ty) => ty,
None => {
return DummyResult::raw_ty(t.span);
}
};
// Keep going, outside-in.
//
let fully_expanded = fld.fold_ty(expanded_ty);
fld.cx.bt_pop();
fully_expanded.map(|t| ast::Ty {
id: ast::DUMMY_NODE_ID,
node: t.node,
span: t.span,
})
}
_ => t
};
fold::noop_fold_ty(t, fld)
}
/// A tree-folder that performs macro expansion
pub struct MacroExpander<'a, 'b:'a> {
pub cx: &'a mut ExtCtxt<'b>,
......@@ -1602,6 +1631,10 @@ fn fold_impl_item(&mut self, i: P<ast::ImplItem>) -> SmallVector<P<ast::ImplItem
.into_iter().map(|i| i.expect_impl_item()).collect()
}
fn fold_ty(&mut self, ty: P<ast::Ty>) -> P<ast::Ty> {
expand_type(ty, self)
}
fn new_span(&mut self, span: Span) -> Span {
new_span(self.cx, span)
}
......@@ -1748,6 +1781,10 @@ fn mark_impl_item(ii: P<ast::ImplItem>, m: Mrk) -> P<ast::ImplItem> {
.expect_one("marking an impl item didn't return exactly one impl item")
}
fn mark_ty(ty: P<ast::Ty>, m: Mrk) -> P<ast::Ty> {
Marker { mark: m }.fold_ty(ty)
}
/// Check that there are no macro invocations left in the AST:
pub fn check_for_macros(sess: &parse::ParseSess, krate: &ast::Crate) {
visit::walk_crate(&mut MacroExterminator{sess:sess}, krate);
......
......@@ -117,6 +117,12 @@ fn make_stmts(self: Box<ParserAnyMacro<'a>>)
self.ensure_complete_parse(false);
Some(ret)
}
fn make_ty(self: Box<ParserAnyMacro<'a>>) -> Option<P<ast::Ty>> {
let ret = self.parser.borrow_mut().parse_ty();
self.ensure_complete_parse(true);
Some(ret)
}
}
struct MacroRulesMacroExpander {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册