about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ext/base.rs6
-rw-r--r--src/libsyntax/ext/expand.rs22
2 files changed, 27 insertions, 1 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index edd66b50286..7d802d953b3 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -420,9 +420,13 @@ impl MacResult for DummyResult {
 pub enum SyntaxExtension {
     /// A syntax extension that is attached to an item and creates new items
     /// based upon it.
+    Decorator(Box<ItemDecorator + 'static>),
+
+    /// A syntax extension that is attached to an item and creates new items
+    /// based upon it.
     ///
     /// `#[derive(...)]` is an `ItemDecorator`.
-    Decorator(Box<ItemDecorator + 'static>),
+    MultiDecorator(Box<MultiItemDecorator + 'static>),
 
     /// A syntax extension that is attached to an item and modifies it
     /// in-place.
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 5736400313e..dbbcee0d9d8 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -1096,6 +1096,28 @@ fn expand_annotatable(a: Annotatable,
 
                     fld.cx.bt_pop();
                 }
+                MultiDecorator(ref dec) => {
+                    attr::mark_used(attr);
+
+                    fld.cx.bt_push(ExpnInfo {
+                        call_site: attr.span,
+                        callee: NameAndSpan {
+                            name: mname.get().to_string(),
+                            format: MacroAttribute,
+                            span: None
+                        }
+                    });
+
+                    // we'd ideally decorator_items.push_all(expand_item(item, fld)),
+                    // but that double-mut-borrows fld
+                    let mut items: SmallVector<P<ast::Item>> = SmallVector::zero();
+                    dec.expand(fld.cx, attr.span, &*attr.node.value, a,
+                               box |&mut: item| items.push(item));
+                    decorator_items.extend(items.into_iter()
+                        .flat_map(|item| expand_item(item, fld).into_iter()));
+
+                    fld.cx.bt_pop();
+                }
                 _ => new_attrs.push((*attr).clone()),
             },
             _ => new_attrs.push((*attr).clone()),