Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/nameres/proc_macro.rs')
| -rw-r--r-- | crates/hir-def/src/nameres/proc_macro.rs | 69 |
1 files changed, 32 insertions, 37 deletions
diff --git a/crates/hir-def/src/nameres/proc_macro.rs b/crates/hir-def/src/nameres/proc_macro.rs index cd8882183b..91d664938b 100644 --- a/crates/hir-def/src/nameres/proc_macro.rs +++ b/crates/hir-def/src/nameres/proc_macro.rs @@ -2,9 +2,12 @@ use hir_expand::name::{AsName, Name}; use intern::sym; +use itertools::Itertools; -use crate::attr::Attrs; -use crate::tt::{Leaf, TokenTree, TopSubtree, TtElement}; +use crate::{ + item_tree::Attrs, + tt::{Leaf, TopSubtree, TtElement}, +}; #[derive(Debug, PartialEq, Eq)] pub struct ProcMacroDef { @@ -29,8 +32,8 @@ impl ProcMacroKind { } } -impl Attrs { - pub fn parse_proc_macro_decl(&self, func_name: &Name) -> Option<ProcMacroDef> { +impl Attrs<'_> { + pub(crate) fn parse_proc_macro_decl(&self, func_name: &Name) -> Option<ProcMacroDef> { if self.is_proc_macro() { Some(ProcMacroDef { name: func_name.clone(), kind: ProcMacroKind::Bang }) } else if self.is_proc_macro_attribute() { @@ -51,51 +54,43 @@ impl Attrs { } } - pub fn parse_proc_macro_derive(&self) -> Option<(Name, Box<[Name]>)> { + pub(crate) fn parse_proc_macro_derive(&self) -> Option<(Name, Box<[Name]>)> { let derive = self.by_key(sym::proc_macro_derive).tt_values().next()?; parse_macro_name_and_helper_attrs(derive) } - - pub fn parse_rustc_builtin_macro(&self) -> Option<(Name, Box<[Name]>)> { - let derive = self.by_key(sym::rustc_builtin_macro).tt_values().next()?; - parse_macro_name_and_helper_attrs(derive) - } } // This fn is intended for `#[proc_macro_derive(..)]` and `#[rustc_builtin_macro(..)]`, which have // the same structure. -#[rustfmt::skip] pub(crate) fn parse_macro_name_and_helper_attrs(tt: &TopSubtree) -> Option<(Name, Box<[Name]>)> { - match tt.token_trees().flat_tokens() { + if let Some([TtElement::Leaf(Leaf::Ident(trait_name))]) = + tt.token_trees().iter().collect_array() + { // `#[proc_macro_derive(Trait)]` // `#[rustc_builtin_macro(Trait)]` - [TokenTree::Leaf(Leaf::Ident(trait_name))] => Some((trait_name.as_name(), Box::new([]))), - + Some((trait_name.as_name(), Box::new([]))) + } else if let Some( + [ + TtElement::Leaf(Leaf::Ident(trait_name)), + TtElement::Leaf(Leaf::Punct(comma)), + TtElement::Leaf(Leaf::Ident(attributes)), + TtElement::Subtree(_, helpers), + ], + ) = tt.token_trees().iter().collect_array() + && comma.char == ',' + && attributes.sym == sym::attributes + { // `#[proc_macro_derive(Trait, attributes(helper1, helper2, ...))]` // `#[rustc_builtin_macro(Trait, attributes(helper1, helper2, ...))]` - [ - TokenTree::Leaf(Leaf::Ident(trait_name)), - TokenTree::Leaf(Leaf::Punct(comma)), - TokenTree::Leaf(Leaf::Ident(attributes)), - TokenTree::Subtree(_), - .. - ] if comma.char == ',' && attributes.sym == sym::attributes => - { - let helpers = tt::TokenTreesView::new(&tt.token_trees().flat_tokens()[3..]).try_into_subtree()?; - let helpers = helpers - .iter() - .filter( - |tt| !matches!(tt, TtElement::Leaf(Leaf::Punct(comma)) if comma.char == ','), - ) - .map(|tt| match tt { - TtElement::Leaf(Leaf::Ident(helper)) => Some(helper.as_name()), - _ => None, - }) - .collect::<Option<Box<[_]>>>()?; - - Some((trait_name.as_name(), helpers)) - } + let helpers = helpers + .filter_map(|tt| match tt { + TtElement::Leaf(Leaf::Ident(helper)) => Some(helper.as_name()), + _ => None, + }) + .collect::<Box<[_]>>(); - _ => None, + Some((trait_name.as_name(), helpers)) + } else { + None } } |