]> git.lizzy.rs Git - rust.git/commitdiff
Allow `MultiItemModifier`s to expand into zero or many items
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>
Sun, 12 Jun 2016 16:05:19 +0000 (16:05 +0000)
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>
Thu, 16 Jun 2016 03:55:55 +0000 (03:55 +0000)
src/libsyntax/ext/base.rs
src/libsyntax/ext/expand.rs

index 5d171521b13b2c40045f4d186437b37504cbbf24..d2185df52e0f4745b3dc269492bda0acc712882d 100644 (file)
@@ -123,9 +123,7 @@ fn expand(&self,
     }
 }
 
-// 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 @@ fn expand(&self,
               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]
     }
 }
 
index e7d7b0a6aef06401e4531324c55a8c2d8b45f77d..69e8bfdcea3c891a2c38e327ee12dbbbb7023079 100644 (file)
@@ -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!(),
         }