Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir_def/src/attr.rs')
-rw-r--r--crates/hir_def/src/attr.rs60
1 files changed, 27 insertions, 33 deletions
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs
index 4f68c91cc9..fd45eccf5a 100644
--- a/crates/hir_def/src/attr.rs
+++ b/crates/hir_def/src/attr.rs
@@ -8,7 +8,7 @@ use either::Either;
use hir_expand::{hygiene::Hygiene, name::AsName, AstId, InFile};
use itertools::Itertools;
use la_arena::ArenaMap;
-use mbe::{syntax_node_to_token_tree, DelimiterKind};
+use mbe::{syntax_node_to_token_tree, DelimiterKind, Punct};
use smallvec::{smallvec, SmallVec};
use syntax::{
ast::{self, AstNode, HasAttrs, IsString},
@@ -722,41 +722,35 @@ impl Attr {
/// Parses this attribute as a `#[derive]`, returns an iterator that yields all contained paths
/// to derive macros.
///
- /// Returns `None` when the attribute is not a well-formed `#[derive]` attribute.
+ /// Returns `None` when the attribute does not have a well-formed `#[derive]` attribute input.
pub(crate) fn parse_derive(&self) -> Option<impl Iterator<Item = ModPath>> {
- if self.path.as_ident() != Some(&hir_expand::name![derive]) {
- return None;
- }
-
- match self.input.as_deref() {
- Some(AttrInput::TokenTree(args, _)) => {
- let mut counter = 0;
- let paths = args
- .token_trees
- .iter()
- .group_by(move |tt| {
- match tt {
- tt::TokenTree::Leaf(tt::Leaf::Punct(p)) if p.char == ',' => {
- counter += 1;
- }
- _ => {}
- }
- counter
- })
- .into_iter()
- .map(|(_, tts)| {
- let segments = tts.filter_map(|tt| match tt {
- tt::TokenTree::Leaf(tt::Leaf::Ident(id)) => Some(id.as_name()),
- _ => None,
- });
- ModPath::from_segments(PathKind::Plain, segments)
- })
- .collect::<Vec<_>>();
-
- Some(paths.into_iter())
+ if let Some(AttrInput::TokenTree(args, _)) = self.input.as_deref() {
+ if args.delimiter_kind() != Some(DelimiterKind::Parenthesis) {
+ return None;
}
- _ => None,
+ let mut counter = 0;
+ let paths = args
+ .token_trees
+ .iter()
+ .group_by(move |tt| {
+ if let tt::TokenTree::Leaf(tt::Leaf::Punct(Punct { char: ',', .. })) = tt {
+ counter += 1;
+ }
+ counter
+ })
+ .into_iter()
+ .map(|(_, tts)| {
+ let segments = tts.filter_map(|tt| match tt {
+ tt::TokenTree::Leaf(tt::Leaf::Ident(id)) => Some(id.as_name()),
+ _ => None,
+ });
+ ModPath::from_segments(PathKind::Plain, segments)
+ })
+ .collect::<Vec<_>>();
+
+ return Some(paths.into_iter());
}
+ None
}
pub fn string_value(&self) -> Option<&SmolStr> {