about summary refs log tree commit diff
path: root/src/libsyntax/ext
diff options
context:
space:
mode:
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-06-12 16:05:19 +0000
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-06-16 03:55:55 +0000
commitac1a1d32f60c9bff72bf77d5d94ad8ce36106e00 (patch)
treef12dd16dcbaa1f449bbf14268866fbf3a2630b7f /src/libsyntax/ext
parent34191ed1c8484bb2feb14369fd638c2671854c70 (diff)
downloadrust-ac1a1d32f60c9bff72bf77d5d94ad8ce36106e00.tar.gz
rust-ac1a1d32f60c9bff72bf77d5d94ad8ce36106e00.zip
Allow `MultiItemModifier`s to expand into zero or many items
Diffstat (limited to 'src/libsyntax/ext')
-rw-r--r--src/libsyntax/ext/base.rs24
-rw-r--r--src/libsyntax/ext/expand.rs2
2 files changed, 14 insertions, 12 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 5d171521b13..d2185df52e0 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -123,9 +123,7 @@ impl<F> MultiItemDecorator for F
     }
 }
 
-// A more flexible ItemKind::Modifier (ItemKind::Modifier should go away, eventually, FIXME).
-// meta_item is the annotation, item is the item being modified, parent_item
-// is the impl or trait item is declared in if item is part of such a thing.
+// `meta_item` is the annotation, and `item` is the item being modified.
 // FIXME Decorators should follow the same pattern too.
 pub trait MultiItemModifier {
     fn expand(&self,
@@ -133,22 +131,26 @@ pub trait MultiItemModifier {
               span: Span,
               meta_item: &ast::MetaItem,
               item: Annotatable)
-              -> Annotatable;
+              -> Vec<Annotatable>;
 }
 
-impl<F> MultiItemModifier for F
-    where F: Fn(&mut ExtCtxt,
-                Span,
-                &ast::MetaItem,
-                Annotatable) -> Annotatable
+impl<F, T> MultiItemModifier for F
+    where F: Fn(&mut ExtCtxt, Span, &ast::MetaItem, Annotatable) -> T,
+          T: Into<Vec<Annotatable>>,
 {
     fn expand(&self,
               ecx: &mut ExtCtxt,
               span: Span,
               meta_item: &ast::MetaItem,
               item: Annotatable)
-              -> Annotatable {
-        (*self)(ecx, span, meta_item, item)
+              -> Vec<Annotatable> {
+        (*self)(ecx, span, meta_item, item).into()
+    }
+}
+
+impl Into<Vec<Annotatable>> for Annotatable {
+    fn into(self) -> Vec<Annotatable> {
+        vec![self]
     }
 }
 
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index e7d7b0a6aef..69e8bfdcea3 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -865,7 +865,7 @@ fn expand_annotatable(mut item: Annotatable, fld: &mut MacroExpander) -> SmallVe
                 });
                 let modified = mac.expand(fld.cx, attr.span, &attr.node.value, item);
                 fld.cx.bt_pop();
-                expand_annotatable(modified, fld)
+                modified.into_iter().flat_map(|it| expand_annotatable(it, fld)).collect()
             }
             _ => unreachable!(),
         }