Rollup merge of #34213 - josephDunne:trait_item_macros, r=jseyfried

**syntax-[breaking-change]** cc #31645
New `TraitItemKind::Macro` variant

This change adds support for macro expansion inside trait items by adding the new `TraitItemKind::Macro` and associated parsing code.
This commit is contained in:
Jeffrey Seyfried
2016-06-25 22:05:08 +00:00
15 changed files with 240 additions and 88 deletions

View File

@@ -81,8 +81,11 @@ impl_macro_generable! {
"statement", .make_stmts, lift .fold_stmt, lift .visit_stmt, |_span| SmallVector::zero();
SmallVector<P<ast::Item>>:
"item", .make_items, lift .fold_item, lift .visit_item, |_span| SmallVector::zero();
SmallVector<ast::TraitItem>:
"trait item", .make_trait_items, lift .fold_trait_item, lift .visit_trait_item,
|_span| SmallVector::zero();
SmallVector<ast::ImplItem>:
"impl item", .make_impl_items, lift .fold_impl_item, lift .visit_impl_item,
"impl item", .make_impl_items, lift .fold_impl_item, lift .visit_impl_item,
|_span| SmallVector::zero();
}
@@ -754,25 +757,10 @@ fn expand_multi_modified(a: Annotatable, fld: &mut MacroExpander) -> SmallVector
_ => noop_fold_item(it, fld),
}.into_iter().map(|i| Annotatable::Item(i)).collect(),
Annotatable::TraitItem(it) => match it.node {
ast::TraitItemKind::Method(_, Some(_)) => {
let ti = it.unwrap();
SmallVector::one(ast::TraitItem {
id: ti.id,
ident: ti.ident,
attrs: ti.attrs,
node: match ti.node {
ast::TraitItemKind::Method(sig, Some(body)) => {
let (sig, body) = expand_and_rename_method(sig, body, fld);
ast::TraitItemKind::Method(sig, Some(body))
}
_ => unreachable!()
},
span: ti.span,
})
}
_ => fold::noop_fold_trait_item(it.unwrap(), fld)
}.into_iter().map(|ti| Annotatable::TraitItem(P(ti))).collect(),
Annotatable::TraitItem(it) => {
expand_trait_item(it.unwrap(), fld).into_iter().
map(|it| Annotatable::TraitItem(P(it))).collect()
}
Annotatable::ImplItem(ii) => {
expand_impl_item(ii.unwrap(), fld).into_iter().
@@ -900,6 +888,31 @@ fn expand_impl_item(ii: ast::ImplItem, fld: &mut MacroExpander)
}
}
fn expand_trait_item(ti: ast::TraitItem, fld: &mut MacroExpander)
-> SmallVector<ast::TraitItem> {
match ti.node {
ast::TraitItemKind::Method(_, Some(_)) => {
SmallVector::one(ast::TraitItem {
id: ti.id,
ident: ti.ident,
attrs: ti.attrs,
node: match ti.node {
ast::TraitItemKind::Method(sig, Some(body)) => {
let (sig, body) = expand_and_rename_method(sig, body, fld);
ast::TraitItemKind::Method(sig, Some(body))
}
_ => unreachable!()
},
span: ti.span,
})
}
ast::TraitItemKind::Macro(mac) => {
expand_mac_invoc(mac, None, ti.attrs, ti.span, fld)
}
_ => fold::noop_fold_trait_item(ti, fld)
}
}
/// Given a fn_decl and a block and a MacroExpander, expand the fn_decl, then use the
/// PatIdents in its arguments to perform renaming in the FnDecl and
/// the block, returning both the new FnDecl and the new Block.