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.rs17
1 files changed, 9 insertions, 8 deletions
diff --git a/crates/hir-def/src/nameres/proc_macro.rs b/crates/hir-def/src/nameres/proc_macro.rs
index fd0b52bc7d..b93a1c87b4 100644
--- a/crates/hir-def/src/nameres/proc_macro.rs
+++ b/crates/hir-def/src/nameres/proc_macro.rs
@@ -4,7 +4,7 @@ use hir_expand::name::{AsName, Name};
use intern::sym;
use crate::attr::Attrs;
-use crate::tt::{Leaf, TokenTree};
+use crate::tt::{Leaf, TokenTree, TopSubtree, TtElement};
#[derive(Debug, PartialEq, Eq)]
pub struct ProcMacroDef {
@@ -38,7 +38,7 @@ impl Attrs {
Some(ProcMacroDef { name: func_name.clone(), kind: ProcMacroKind::Attr })
} else if self.by_key(&sym::proc_macro_derive).exists() {
let derive = self.by_key(&sym::proc_macro_derive).tt_values().next()?;
- let def = parse_macro_name_and_helper_attrs(&derive.token_trees)
+ let def = parse_macro_name_and_helper_attrs(derive)
.map(|(name, helpers)| ProcMacroDef { name, kind: ProcMacroKind::Derive { helpers } });
if def.is_none() {
@@ -55,8 +55,8 @@ impl Attrs {
// 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: &[TokenTree]) -> Option<(Name, Box<[Name]>)> {
- match tt {
+pub(crate) fn parse_macro_name_and_helper_attrs(tt: &TopSubtree) -> Option<(Name, Box<[Name]>)> {
+ match tt.token_trees().flat_tokens() {
// `#[proc_macro_derive(Trait)]`
// `#[rustc_builtin_macro(Trait)]`
[TokenTree::Leaf(Leaf::Ident(trait_name))] => Some((trait_name.as_name(), Box::new([]))),
@@ -67,17 +67,18 @@ pub(crate) fn parse_macro_name_and_helper_attrs(tt: &[TokenTree]) -> Option<(Nam
TokenTree::Leaf(Leaf::Ident(trait_name)),
TokenTree::Leaf(Leaf::Punct(comma)),
TokenTree::Leaf(Leaf::Ident(attributes)),
- TokenTree::Subtree(helpers)
+ 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
- .token_trees
.iter()
.filter(
- |tt| !matches!(tt, TokenTree::Leaf(Leaf::Punct(comma)) if comma.char == ','),
+ |tt| !matches!(tt, TtElement::Leaf(Leaf::Punct(comma)) if comma.char == ','),
)
.map(|tt| match tt {
- TokenTree::Leaf(Leaf::Ident(helper)) => Some(helper.as_name()),
+ TtElement::Leaf(Leaf::Ident(helper)) => Some(helper.as_name()),
_ => None,
})
.collect::<Option<Box<[_]>>>()?;