|
11 | 11 | //! The compiler code necessary to implement the `#[derive]` extensions.
|
12 | 12 |
|
13 | 13 | use syntax::ast::{self, MetaItem};
|
| 14 | +use syntax::attr::HasAttrs; |
14 | 15 | use syntax::ext::base::{Annotatable, ExtCtxt};
|
15 | 16 | use syntax::ext::build::AstBuilder;
|
16 | 17 | use syntax::feature_gate;
|
@@ -104,13 +105,37 @@ pub fn expand_derive(cx: &mut ExtCtxt,
|
104 | 105 | }
|
105 | 106 | };
|
106 | 107 |
|
107 |
| - if mitem.value_str().is_some() { |
108 |
| - cx.span_err(mitem.span, "unexpected value in `derive`"); |
| 108 | + let mut derive_attrs = Vec::new(); |
| 109 | + item = item.map_attrs(|attrs| { |
| 110 | + let partition = attrs.into_iter().partition(|attr| &attr.name() == "derive"); |
| 111 | + derive_attrs = partition.0; |
| 112 | + partition.1 |
| 113 | + }); |
| 114 | + |
| 115 | + // Expand `#[derive]`s after other attribute macro invocations. |
| 116 | + if cx.resolver.find_attr_invoc(&mut item.attrs.clone()).is_some() { |
| 117 | + return vec![Annotatable::Item(item.map_attrs(|mut attrs| { |
| 118 | + attrs.push(cx.attribute(span, P(mitem.clone()))); |
| 119 | + attrs.extend(derive_attrs); |
| 120 | + attrs |
| 121 | + }))]; |
109 | 122 | }
|
110 | 123 |
|
111 |
| - let mut traits = mitem.meta_item_list().unwrap_or(&[]).to_owned(); |
112 |
| - if traits.is_empty() { |
113 |
| - cx.span_warn(mitem.span, "empty trait list in `derive`"); |
| 124 | + let get_traits = |mitem: &MetaItem, cx: &ExtCtxt| { |
| 125 | + if mitem.value_str().is_some() { |
| 126 | + cx.span_err(mitem.span, "unexpected value in `derive`"); |
| 127 | + } |
| 128 | + |
| 129 | + let traits = mitem.meta_item_list().unwrap_or(&[]).to_owned(); |
| 130 | + if traits.is_empty() { |
| 131 | + cx.span_warn(mitem.span, "empty trait list in `derive`"); |
| 132 | + } |
| 133 | + traits |
| 134 | + }; |
| 135 | + |
| 136 | + let mut traits = get_traits(mitem, cx); |
| 137 | + for derive_attr in derive_attrs { |
| 138 | + traits.extend(get_traits(&derive_attr.node.value, cx)); |
114 | 139 | }
|
115 | 140 |
|
116 | 141 | // First, weed out malformed #[derive]
|
|
0 commit comments