diff options
| author | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-10-10 08:47:54 +0000 |
|---|---|---|
| committer | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-10-10 22:15:55 +0000 |
| commit | 60a4b69ec09f9110baf22394539592bbce0c839c (patch) | |
| tree | 64976e63c4eaae7b31b84ba5948e5ecd06fe804c /src/libsyntax_ext | |
| parent | a7bfb1aba9d089a0464c03b3841e889c6ee7c4f1 (diff) | |
| download | rust-60a4b69ec09f9110baf22394539592bbce0c839c.tar.gz rust-60a4b69ec09f9110baf22394539592bbce0c839c.zip | |
Expand `#[derive]` attribute macro invocations last.
Diffstat (limited to 'src/libsyntax_ext')
| -rw-r--r-- | src/libsyntax_ext/deriving/mod.rs | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs index fdb10a2beb2..9f99919c895 100644 --- a/src/libsyntax_ext/deriving/mod.rs +++ b/src/libsyntax_ext/deriving/mod.rs @@ -11,6 +11,7 @@ //! The compiler code necessary to implement the `#[derive]` extensions. use syntax::ast::{self, MetaItem}; +use syntax::attr::HasAttrs; use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ext::build::AstBuilder; use syntax::feature_gate; @@ -104,13 +105,37 @@ pub fn expand_derive(cx: &mut ExtCtxt, } }; - if mitem.value_str().is_some() { - cx.span_err(mitem.span, "unexpected value in `derive`"); + let mut derive_attrs = Vec::new(); + item = item.map_attrs(|attrs| { + let partition = attrs.into_iter().partition(|attr| &attr.name() == "derive"); + derive_attrs = partition.0; + partition.1 + }); + + // Expand `#[derive]`s after other attribute macro invocations. + if cx.resolver.find_attr_invoc(&mut item.attrs.clone()).is_some() { + return vec![Annotatable::Item(item.map_attrs(|mut attrs| { + attrs.push(cx.attribute(span, P(mitem.clone()))); + attrs.extend(derive_attrs); + attrs + }))]; } - let mut traits = mitem.meta_item_list().unwrap_or(&[]).to_owned(); - if traits.is_empty() { - cx.span_warn(mitem.span, "empty trait list in `derive`"); + let get_traits = |mitem: &MetaItem, cx: &ExtCtxt| { + if mitem.value_str().is_some() { + cx.span_err(mitem.span, "unexpected value in `derive`"); + } + + let traits = mitem.meta_item_list().unwrap_or(&[]).to_owned(); + if traits.is_empty() { + cx.span_warn(mitem.span, "empty trait list in `derive`"); + } + traits + }; + + let mut traits = get_traits(mitem, cx); + for derive_attr in derive_attrs { + traits.extend(get_traits(&derive_attr.node.value, cx)); } // First, weed out malformed #[derive] |
