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.rs69
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
}
}