Extend macro machinery to expand macros in types
Reapplied the changes from 7aafe24139
to a clean branch of master
This commit is contained in:
@@ -290,6 +290,10 @@ pub trait MacResult {
|
||||
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 @@ make_MacEager! {
|
||||
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 @@ impl MacResult for MacEager {
|
||||
}
|
||||
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 @@ 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 {
|
||||
|
||||
@@ -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 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
|
||||
.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 @@ impl<'a> MacResult for 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 {
|
||||
|
||||
Reference in New Issue
Block a user