diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2021-07-10 17:16:53 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2021-07-13 21:59:22 +0300 |
| commit | 6c9ea1e8a9c899979a8b4dd86b32c4c77f4b6b6a (patch) | |
| tree | e2b7cdc22b7cee2ff382fe124ff3511921f9c38e /compiler/rustc_builtin_macros/src/proc_macro_harness.rs | |
| parent | 3e1c75c6e25a4db968066bd2ef2dabc7c504d7ca (diff) | |
| download | rust-6c9ea1e8a9c899979a8b4dd86b32c4c77f4b6b6a.tar.gz rust-6c9ea1e8a9c899979a8b4dd86b32c4c77f4b6b6a.zip | |
expand: Support helper attributes for built-in derive macros
Diffstat (limited to 'compiler/rustc_builtin_macros/src/proc_macro_harness.rs')
| -rw-r--r-- | compiler/rustc_builtin_macros/src/proc_macro_harness.rs | 83 |
1 files changed, 7 insertions, 76 deletions
diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs index 71bbae1161b..a8c61d53346 100644 --- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs +++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs @@ -5,7 +5,7 @@ use rustc_ast::ptr::P; use rustc_ast::visit::{self, Visitor}; use rustc_ast::{self as ast, NodeId}; use rustc_ast_pretty::pprust; -use rustc_expand::base::{ExtCtxt, ResolverExpand}; +use rustc_expand::base::{parse_macro_name_and_helper_attrs, ExtCtxt, ResolverExpand}; use rustc_expand::expand::{AstFragment, ExpansionConfig}; use rustc_session::Session; use rustc_span::hygiene::AstPass; @@ -109,86 +109,17 @@ impl<'a> CollectProcMacros<'a> { } fn collect_custom_derive(&mut self, item: &'a ast::Item, attr: &'a ast::Attribute) { - // Once we've located the `#[proc_macro_derive]` attribute, verify - // that it's of the form `#[proc_macro_derive(Foo)]` or - // `#[proc_macro_derive(Foo, attributes(A, ..))]` - let list = match attr.meta_item_list() { - Some(list) => list, - None => return, - }; - if list.len() != 1 && list.len() != 2 { - self.handler.span_err(attr.span, "attribute must have either one or two arguments"); - return; - } - let trait_attr = match list[0].meta_item() { - Some(meta_item) => meta_item, - _ => { - self.handler.span_err(list[0].span(), "not a meta item"); - return; - } - }; - let trait_ident = match trait_attr.ident() { - Some(trait_ident) if trait_attr.is_word() => trait_ident, - _ => { - self.handler.span_err(trait_attr.span, "must only be one word"); - return; - } - }; - - if !trait_ident.name.can_be_raw() { - self.handler.span_err( - trait_attr.span, - &format!("`{}` cannot be a name of derive macro", trait_ident), - ); - } - - let attributes_attr = list.get(1); - let proc_attrs: Vec<_> = if let Some(attr) = attributes_attr { - if !attr.has_name(sym::attributes) { - self.handler.span_err(attr.span(), "second argument must be `attributes`") - } - attr.meta_item_list() - .unwrap_or_else(|| { - self.handler - .span_err(attr.span(), "attribute must be of form: `attributes(foo, bar)`"); - &[] - }) - .iter() - .filter_map(|attr| { - let attr = match attr.meta_item() { - Some(meta_item) => meta_item, - _ => { - self.handler.span_err(attr.span(), "not a meta item"); - return None; - } - }; - - let ident = match attr.ident() { - Some(ident) if attr.is_word() => ident, - _ => { - self.handler.span_err(attr.span, "must only be one word"); - return None; - } - }; - if !ident.name.can_be_raw() { - self.handler.span_err( - attr.span, - &format!("`{}` cannot be a name of derive helper attribute", ident), - ); - } - - Some(ident.name) - }) - .collect() - } else { - Vec::new() - }; + let (trait_name, proc_attrs) = + match parse_macro_name_and_helper_attrs(self.handler, attr, "derive") { + Some(name_and_attrs) => name_and_attrs, + None => return, + }; if self.in_root && item.vis.kind.is_pub() { self.macros.push(ProcMacro::Derive(ProcMacroDerive { id: item.id, span: item.span, - trait_name: trait_ident.name, + trait_name, function_name: item.ident, attrs: proc_attrs, })); |
