diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index edd66b502862..7d802d953b35 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -418,11 +418,15 @@ impl MacResult for DummyResult { /// An enum representing the different kinds of syntax extensions. pub enum SyntaxExtension { + /// A syntax extension that is attached to an item and creates new items + /// based upon it. + Decorator(Box), + /// A syntax extension that is attached to an item and creates new items /// based upon it. /// /// `#[derive(...)]` is an `ItemDecorator`. - Decorator(Box), + MultiDecorator(Box), /// 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 5736400313e9..dbbcee0d9d82 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> = 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()),