Extend macro machinery to expand macros in types

Reapplied the changes from 7aafe24139
to a clean branch of master
This commit is contained in:
Jared Roesch
2015-07-25 21:54:19 -07:00
parent edca562c87
commit 9fb11fe9f2
3 changed files with 58 additions and 0 deletions

View File

@@ -290,6 +290,10 @@ pub trait MacResult {
fn make_stmts(self: Box<Self>) -> Option<SmallVector<P<ast::Stmt>>> { fn make_stmts(self: Box<Self>) -> Option<SmallVector<P<ast::Stmt>>> {
make_stmts_default!(self) make_stmts_default!(self)
} }
fn make_ty(self: Box<Self>) -> Option<P<ast::Ty>> {
None
}
} }
macro_rules! make_MacEager { macro_rules! make_MacEager {
@@ -322,6 +326,7 @@ make_MacEager! {
items: SmallVector<P<ast::Item>>, items: SmallVector<P<ast::Item>>,
impl_items: SmallVector<P<ast::ImplItem>>, impl_items: SmallVector<P<ast::ImplItem>>,
stmts: SmallVector<P<ast::Stmt>>, stmts: SmallVector<P<ast::Stmt>>,
ty: P<ast::Ty>,
} }
impl MacResult for MacEager { impl MacResult for MacEager {
@@ -359,6 +364,10 @@ impl MacResult for MacEager {
} }
None None
} }
fn make_ty(self: Box<Self>) -> Option<P<ast::Ty>> {
self.ty
}
} }
/// Fill-in macro expansion result, to allow compilation to continue /// Fill-in macro expansion result, to allow compilation to continue
@@ -405,6 +414,12 @@ impl DummyResult {
} }
} }
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 { impl MacResult for DummyResult {

View File

@@ -1552,6 +1552,35 @@ fn expand_and_rename_method(sig: ast::MethodSig, body: P<ast::Block>,
}, rewritten_body) }, 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 /// A tree-folder that performs macro expansion
pub struct MacroExpander<'a, 'b:'a> { pub struct MacroExpander<'a, 'b:'a> {
pub cx: &'a mut ExtCtxt<'b>, pub cx: &'a mut ExtCtxt<'b>,
@@ -1602,6 +1631,10 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
.into_iter().map(|i| i.expect_impl_item()).collect() .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 { fn new_span(&mut self, span: Span) -> Span {
new_span(self.cx, 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") .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: /// Check that there are no macro invocations left in the AST:
pub fn check_for_macros(sess: &parse::ParseSess, krate: &ast::Crate) { pub fn check_for_macros(sess: &parse::ParseSess, krate: &ast::Crate) {
visit::walk_crate(&mut MacroExterminator{sess:sess}, krate); visit::walk_crate(&mut MacroExterminator{sess:sess}, krate);

View File

@@ -117,6 +117,12 @@ impl<'a> MacResult for ParserAnyMacro<'a> {
self.ensure_complete_parse(false); self.ensure_complete_parse(false);
Some(ret) 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 { struct MacroRulesMacroExpander {