Allow MultiItemModifiers to expand into zero or many items

This commit is contained in:
Jeffrey Seyfried
2016-06-12 16:05:19 +00:00
parent 34191ed1c8
commit ac1a1d32f6
2 changed files with 14 additions and 12 deletions

View File

@@ -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, and `item` is the item being modified.
// 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.
// FIXME Decorators should follow the same pattern too. // FIXME Decorators should follow the same pattern too.
pub trait MultiItemModifier { pub trait MultiItemModifier {
fn expand(&self, fn expand(&self,
@@ -133,22 +131,26 @@ pub trait MultiItemModifier {
span: Span, span: Span,
meta_item: &ast::MetaItem, meta_item: &ast::MetaItem,
item: Annotatable) item: Annotatable)
-> Annotatable; -> Vec<Annotatable>;
} }
impl<F> MultiItemModifier for F impl<F, T> MultiItemModifier for F
where F: Fn(&mut ExtCtxt, where F: Fn(&mut ExtCtxt, Span, &ast::MetaItem, Annotatable) -> T,
Span, T: Into<Vec<Annotatable>>,
&ast::MetaItem,
Annotatable) -> Annotatable
{ {
fn expand(&self, fn expand(&self,
ecx: &mut ExtCtxt, ecx: &mut ExtCtxt,
span: Span, span: Span,
meta_item: &ast::MetaItem, meta_item: &ast::MetaItem,
item: Annotatable) item: Annotatable)
-> Annotatable { -> Vec<Annotatable> {
(*self)(ecx, span, meta_item, item) (*self)(ecx, span, meta_item, item).into()
}
}
impl Into<Vec<Annotatable>> for Annotatable {
fn into(self) -> Vec<Annotatable> {
vec![self]
} }
} }

View 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); let modified = mac.expand(fld.cx, attr.span, &attr.node.value, item);
fld.cx.bt_pop(); fld.cx.bt_pop();
expand_annotatable(modified, fld) modified.into_iter().flat_map(|it| expand_annotatable(it, fld)).collect()
} }
_ => unreachable!(), _ => unreachable!(),
} }