diff options
| author | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-06-25 22:05:08 +0000 |
|---|---|---|
| committer | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-06-25 22:35:01 +0000 |
| commit | f0310e061b9d0a7d8dc515390fa68dfb6318df4b (patch) | |
| tree | 09633b17c39077a6128e2a7a34d86f7daffcfbab /src/libsyntax/ext | |
| parent | b8214dc6c6fc20d0a660fb5700dca9ebf51ebe89 (diff) | |
| parent | dc3d878e0f513bde3dfad69d4f2722e2884c23a3 (diff) | |
| download | rust-f0310e061b9d0a7d8dc515390fa68dfb6318df4b.tar.gz rust-f0310e061b9d0a7d8dc515390fa68dfb6318df4b.zip | |
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.
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/base.rs | 18 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 53 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_rules.rs | 15 |
3 files changed, 66 insertions, 20 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index f2a005573d5..9d467b4095a 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -241,6 +241,11 @@ pub trait MacResult { None } + /// Create zero or more trait items. + fn make_trait_items(self: Box<Self>) -> Option<SmallVector<ast::TraitItem>> { + None + } + /// Create a pattern. fn make_pat(self: Box<Self>) -> Option<P<ast::Pat>> { None @@ -288,6 +293,7 @@ make_MacEager! { pat: P<ast::Pat>, items: SmallVector<P<ast::Item>>, impl_items: SmallVector<ast::ImplItem>, + trait_items: SmallVector<ast::TraitItem>, stmts: SmallVector<ast::Stmt>, ty: P<ast::Ty>, } @@ -305,6 +311,10 @@ impl MacResult for MacEager { self.impl_items } + fn make_trait_items(self: Box<Self>) -> Option<SmallVector<ast::TraitItem>> { + self.trait_items + } + fn make_stmts(self: Box<Self>) -> Option<SmallVector<ast::Stmt>> { match self.stmts.as_ref().map_or(0, |s| s.len()) { 0 => make_stmts_default!(self), @@ -413,6 +423,14 @@ impl MacResult for DummyResult { } } + fn make_trait_items(self: Box<DummyResult>) -> Option<SmallVector<ast::TraitItem>> { + if self.expr_only { + None + } else { + Some(SmallVector::zero()) + } + } + fn make_stmts(self: Box<DummyResult>) -> Option<SmallVector<ast::Stmt>> { Some(SmallVector::one( codemap::respan(self.span, diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 5beb4937207..126f39bcb0e 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -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. diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index bbe989b0f40..fe98394c3e4 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -100,6 +100,21 @@ impl<'a> MacResult for ParserAnyMacro<'a> { Some(ret) } + fn make_trait_items(self: Box<ParserAnyMacro<'a>>) + -> Option<SmallVector<ast::TraitItem>> { + let mut ret = SmallVector::zero(); + loop { + let mut parser = self.parser.borrow_mut(); + match parser.token { + token::Eof => break, + _ => ret.push(panictry!(parser.parse_trait_item())) + } + } + self.ensure_complete_parse(false, "item"); + Some(ret) + } + + fn make_stmts(self: Box<ParserAnyMacro<'a>>) -> Option<SmallVector<ast::Stmt>> { let mut ret = SmallVector::zero(); |
