]> git.lizzy.rs Git - rust.git/blob - crates/syntax/src/ast/node_ext.rs
Make replace_derive_with_manual_impl work again
[rust.git] / crates / syntax / src / ast / node_ext.rs
1 //! Various extension methods to ast Nodes, which are hard to code-generate.
2 //! Extensions for various expressions live in a sibling `expr_extensions` module.
3 //!
4 //! These methods should only do simple, shallow tasks related to the syntax of the node itself.
5
6 use std::{borrow::Cow, fmt, iter::successors};
7
8 use itertools::Itertools;
9 use parser::SyntaxKind;
10 use rowan::{GreenNodeData, GreenTokenData};
11
12 use crate::{
13     ast::{self, support, AstNode, AstToken, HasAttrs, HasGenericParams, HasName, SyntaxNode},
14     NodeOrToken, SmolStr, SyntaxElement, SyntaxToken, TokenText, T,
15 };
16
17 impl ast::Lifetime {
18     pub fn text(&self) -> TokenText<'_> {
19         text_of_first_token(self.syntax())
20     }
21 }
22
23 impl ast::Name {
24     pub fn text(&self) -> TokenText<'_> {
25         text_of_first_token(self.syntax())
26     }
27 }
28
29 impl ast::NameRef {
30     pub fn text(&self) -> TokenText<'_> {
31         text_of_first_token(self.syntax())
32     }
33
34     pub fn as_tuple_field(&self) -> Option<usize> {
35         self.text().parse().ok()
36     }
37 }
38
39 fn text_of_first_token(node: &SyntaxNode) -> TokenText<'_> {
40     fn first_token(green_ref: &GreenNodeData) -> &GreenTokenData {
41         green_ref.children().next().and_then(NodeOrToken::into_token).unwrap()
42     }
43
44     match node.green() {
45         Cow::Borrowed(green_ref) => TokenText::borrowed(first_token(green_ref).text()),
46         Cow::Owned(green) => TokenText::owned(first_token(&green).to_owned()),
47     }
48 }
49
50 impl ast::HasModuleItem for ast::StmtList {}
51
52 impl ast::BlockExpr {
53     // FIXME: remove all these methods, they belong to ast::StmtList
54     pub fn statements(&self) -> impl Iterator<Item = ast::Stmt> {
55         self.stmt_list().into_iter().flat_map(|it| it.statements())
56     }
57     pub fn tail_expr(&self) -> Option<ast::Expr> {
58         self.stmt_list()?.tail_expr()
59     }
60 }
61
62 #[derive(Debug, PartialEq, Eq, Clone)]
63 pub enum Macro {
64     MacroRules(ast::MacroRules),
65     MacroDef(ast::MacroDef),
66 }
67
68 impl From<ast::MacroRules> for Macro {
69     fn from(it: ast::MacroRules) -> Self {
70         Macro::MacroRules(it)
71     }
72 }
73
74 impl From<ast::MacroDef> for Macro {
75     fn from(it: ast::MacroDef) -> Self {
76         Macro::MacroDef(it)
77     }
78 }
79
80 impl AstNode for Macro {
81     fn can_cast(kind: SyntaxKind) -> bool {
82         matches!(kind, SyntaxKind::MACRO_RULES | SyntaxKind::MACRO_DEF)
83     }
84     fn cast(syntax: SyntaxNode) -> Option<Self> {
85         let res = match syntax.kind() {
86             SyntaxKind::MACRO_RULES => Macro::MacroRules(ast::MacroRules { syntax }),
87             SyntaxKind::MACRO_DEF => Macro::MacroDef(ast::MacroDef { syntax }),
88             _ => return None,
89         };
90         Some(res)
91     }
92     fn syntax(&self) -> &SyntaxNode {
93         match self {
94             Macro::MacroRules(it) => it.syntax(),
95             Macro::MacroDef(it) => it.syntax(),
96         }
97     }
98 }
99
100 impl HasName for Macro {
101     fn name(&self) -> Option<ast::Name> {
102         match self {
103             Macro::MacroRules(mac) => mac.name(),
104             Macro::MacroDef(mac) => mac.name(),
105         }
106     }
107 }
108
109 impl HasAttrs for Macro {}
110
111 impl From<ast::AssocItem> for ast::Item {
112     fn from(assoc: ast::AssocItem) -> Self {
113         match assoc {
114             ast::AssocItem::Const(it) => ast::Item::Const(it),
115             ast::AssocItem::Fn(it) => ast::Item::Fn(it),
116             ast::AssocItem::MacroCall(it) => ast::Item::MacroCall(it),
117             ast::AssocItem::TypeAlias(it) => ast::Item::TypeAlias(it),
118         }
119     }
120 }
121
122 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
123 pub enum AttrKind {
124     Inner,
125     Outer,
126 }
127
128 impl AttrKind {
129     /// Returns `true` if the attr_kind is [`Inner`](Self::Inner).
130     pub fn is_inner(&self) -> bool {
131         matches!(self, Self::Inner)
132     }
133
134     /// Returns `true` if the attr_kind is [`Outer`](Self::Outer).
135     pub fn is_outer(&self) -> bool {
136         matches!(self, Self::Outer)
137     }
138 }
139
140 impl ast::Attr {
141     pub fn as_simple_atom(&self) -> Option<SmolStr> {
142         let meta = self.meta()?;
143         if meta.eq_token().is_some() || meta.token_tree().is_some() {
144             return None;
145         }
146         self.simple_name()
147     }
148
149     pub fn as_simple_call(&self) -> Option<(SmolStr, ast::TokenTree)> {
150         let tt = self.meta()?.token_tree()?;
151         Some((self.simple_name()?, tt))
152     }
153
154     pub fn simple_name(&self) -> Option<SmolStr> {
155         let path = self.meta()?.path()?;
156         match (path.segment(), path.qualifier()) {
157             (Some(segment), None) => Some(segment.syntax().first_token()?.text().into()),
158             _ => None,
159         }
160     }
161
162     pub fn kind(&self) -> AttrKind {
163         match self.excl_token() {
164             Some(_) => AttrKind::Inner,
165             None => AttrKind::Outer,
166         }
167     }
168
169     pub fn path(&self) -> Option<ast::Path> {
170         self.meta()?.path()
171     }
172
173     pub fn expr(&self) -> Option<ast::Expr> {
174         self.meta()?.expr()
175     }
176
177     pub fn token_tree(&self) -> Option<ast::TokenTree> {
178         self.meta()?.token_tree()
179     }
180 }
181
182 #[derive(Debug, Clone, PartialEq, Eq)]
183 pub enum PathSegmentKind {
184     Name(ast::NameRef),
185     Type { type_ref: Option<ast::Type>, trait_ref: Option<ast::PathType> },
186     SelfKw,
187     SuperKw,
188     CrateKw,
189 }
190
191 impl ast::PathSegment {
192     pub fn parent_path(&self) -> ast::Path {
193         self.syntax()
194             .parent()
195             .and_then(ast::Path::cast)
196             .expect("segments are always nested in paths")
197     }
198
199     pub fn crate_token(&self) -> Option<SyntaxToken> {
200         self.name_ref().and_then(|it| it.crate_token())
201     }
202
203     pub fn self_token(&self) -> Option<SyntaxToken> {
204         self.name_ref().and_then(|it| it.self_token())
205     }
206
207     pub fn super_token(&self) -> Option<SyntaxToken> {
208         self.name_ref().and_then(|it| it.super_token())
209     }
210
211     pub fn kind(&self) -> Option<PathSegmentKind> {
212         let res = if let Some(name_ref) = self.name_ref() {
213             match name_ref.syntax().first_token().map(|it| it.kind()) {
214                 Some(T![self]) => PathSegmentKind::SelfKw,
215                 Some(T![super]) => PathSegmentKind::SuperKw,
216                 Some(T![crate]) => PathSegmentKind::CrateKw,
217                 _ => PathSegmentKind::Name(name_ref),
218             }
219         } else {
220             match self.syntax().first_child_or_token()?.kind() {
221                 T![<] => {
222                     // <T> or <T as Trait>
223                     // T is any TypeRef, Trait has to be a PathType
224                     let mut type_refs =
225                         self.syntax().children().filter(|node| ast::Type::can_cast(node.kind()));
226                     let type_ref = type_refs.next().and_then(ast::Type::cast);
227                     let trait_ref = type_refs.next().and_then(ast::PathType::cast);
228                     PathSegmentKind::Type { type_ref, trait_ref }
229                 }
230                 _ => return None,
231             }
232         };
233         Some(res)
234     }
235 }
236
237 impl ast::Path {
238     pub fn parent_path(&self) -> Option<ast::Path> {
239         self.syntax().parent().and_then(ast::Path::cast)
240     }
241
242     pub fn as_single_segment(&self) -> Option<ast::PathSegment> {
243         match self.qualifier() {
244             Some(_) => None,
245             None => self.segment(),
246         }
247     }
248
249     pub fn as_single_name_ref(&self) -> Option<ast::NameRef> {
250         match self.qualifier() {
251             Some(_) => None,
252             None => self.segment()?.name_ref(),
253         }
254     }
255
256     pub fn first_qualifier_or_self(&self) -> ast::Path {
257         successors(Some(self.clone()), ast::Path::qualifier).last().unwrap()
258     }
259
260     pub fn first_segment(&self) -> Option<ast::PathSegment> {
261         self.first_qualifier_or_self().segment()
262     }
263
264     pub fn segments(&self) -> impl Iterator<Item = ast::PathSegment> + Clone {
265         successors(self.first_segment(), |p| {
266             p.parent_path().parent_path().and_then(|p| p.segment())
267         })
268     }
269
270     pub fn qualifiers(&self) -> impl Iterator<Item = ast::Path> + Clone {
271         successors(self.qualifier(), |p| p.qualifier())
272     }
273
274     pub fn top_path(&self) -> ast::Path {
275         let mut this = self.clone();
276         while let Some(path) = this.parent_path() {
277             this = path;
278         }
279         this
280     }
281 }
282
283 impl ast::Use {
284     pub fn is_simple_glob(&self) -> bool {
285         self.use_tree().map_or(false, |use_tree| {
286             use_tree.use_tree_list().is_none() && use_tree.star_token().is_some()
287         })
288     }
289 }
290
291 impl ast::UseTree {
292     pub fn is_simple_path(&self) -> bool {
293         self.use_tree_list().is_none() && self.star_token().is_none()
294     }
295 }
296
297 impl ast::UseTreeList {
298     pub fn parent_use_tree(&self) -> ast::UseTree {
299         self.syntax()
300             .parent()
301             .and_then(ast::UseTree::cast)
302             .expect("UseTreeLists are always nested in UseTrees")
303     }
304
305     pub fn has_inner_comment(&self) -> bool {
306         self.syntax()
307             .children_with_tokens()
308             .filter_map(|it| it.into_token())
309             .find_map(ast::Comment::cast)
310             .is_some()
311     }
312 }
313
314 impl ast::Impl {
315     pub fn self_ty(&self) -> Option<ast::Type> {
316         match self.target() {
317             (Some(t), None) | (_, Some(t)) => Some(t),
318             _ => None,
319         }
320     }
321
322     pub fn trait_(&self) -> Option<ast::Type> {
323         match self.target() {
324             (Some(t), Some(_)) => Some(t),
325             _ => None,
326         }
327     }
328
329     fn target(&self) -> (Option<ast::Type>, Option<ast::Type>) {
330         let mut types = support::children(self.syntax());
331         let first = types.next();
332         let second = types.next();
333         (first, second)
334     }
335
336     pub fn for_trait_name_ref(name_ref: &ast::NameRef) -> Option<ast::Impl> {
337         let this = name_ref.syntax().ancestors().find_map(ast::Impl::cast)?;
338         if this.trait_()?.syntax().text_range().start() == name_ref.syntax().text_range().start() {
339             Some(this)
340         } else {
341             None
342         }
343     }
344 }
345
346 #[derive(Debug, Clone, PartialEq, Eq)]
347 pub enum StructKind {
348     Record(ast::RecordFieldList),
349     Tuple(ast::TupleFieldList),
350     Unit,
351 }
352
353 impl StructKind {
354     fn from_node<N: AstNode>(node: &N) -> StructKind {
355         if let Some(nfdl) = support::child::<ast::RecordFieldList>(node.syntax()) {
356             StructKind::Record(nfdl)
357         } else if let Some(pfl) = support::child::<ast::TupleFieldList>(node.syntax()) {
358             StructKind::Tuple(pfl)
359         } else {
360             StructKind::Unit
361         }
362     }
363 }
364
365 impl ast::Struct {
366     pub fn kind(&self) -> StructKind {
367         StructKind::from_node(self)
368     }
369 }
370
371 impl ast::RecordExprField {
372     pub fn for_field_name(field_name: &ast::NameRef) -> Option<ast::RecordExprField> {
373         let candidate = Self::for_name_ref(field_name)?;
374         if candidate.field_name().as_ref() == Some(field_name) {
375             Some(candidate)
376         } else {
377             None
378         }
379     }
380
381     pub fn for_name_ref(name_ref: &ast::NameRef) -> Option<ast::RecordExprField> {
382         let syn = name_ref.syntax();
383         syn.parent()
384             .and_then(ast::RecordExprField::cast)
385             .or_else(|| syn.ancestors().nth(4).and_then(ast::RecordExprField::cast))
386     }
387
388     /// Deals with field init shorthand
389     pub fn field_name(&self) -> Option<ast::NameRef> {
390         if let Some(name_ref) = self.name_ref() {
391             return Some(name_ref);
392         }
393         if let ast::Expr::PathExpr(expr) = self.expr()? {
394             let path = expr.path()?;
395             let segment = path.segment()?;
396             let name_ref = segment.name_ref()?;
397             if path.qualifier().is_none() {
398                 return Some(name_ref);
399             }
400         }
401         None
402     }
403 }
404
405 #[derive(Debug, Clone)]
406 pub enum NameLike {
407     NameRef(ast::NameRef),
408     Name(ast::Name),
409     Lifetime(ast::Lifetime),
410 }
411
412 impl NameLike {
413     pub fn as_name_ref(&self) -> Option<&ast::NameRef> {
414         match self {
415             NameLike::NameRef(name_ref) => Some(name_ref),
416             _ => None,
417         }
418     }
419 }
420
421 impl ast::AstNode for NameLike {
422     fn can_cast(kind: SyntaxKind) -> bool {
423         matches!(kind, SyntaxKind::NAME | SyntaxKind::NAME_REF | SyntaxKind::LIFETIME)
424     }
425     fn cast(syntax: SyntaxNode) -> Option<Self> {
426         let res = match syntax.kind() {
427             SyntaxKind::NAME => NameLike::Name(ast::Name { syntax }),
428             SyntaxKind::NAME_REF => NameLike::NameRef(ast::NameRef { syntax }),
429             SyntaxKind::LIFETIME => NameLike::Lifetime(ast::Lifetime { syntax }),
430             _ => return None,
431         };
432         Some(res)
433     }
434     fn syntax(&self) -> &SyntaxNode {
435         match self {
436             NameLike::NameRef(it) => it.syntax(),
437             NameLike::Name(it) => it.syntax(),
438             NameLike::Lifetime(it) => it.syntax(),
439         }
440     }
441 }
442
443 const _: () = {
444     use ast::{Lifetime, Name, NameRef};
445     stdx::impl_from!(NameRef, Name, Lifetime for NameLike);
446 };
447
448 #[derive(Debug, Clone, PartialEq)]
449 pub enum NameOrNameRef {
450     Name(ast::Name),
451     NameRef(ast::NameRef),
452 }
453
454 impl fmt::Display for NameOrNameRef {
455     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
456         match self {
457             NameOrNameRef::Name(it) => fmt::Display::fmt(it, f),
458             NameOrNameRef::NameRef(it) => fmt::Display::fmt(it, f),
459         }
460     }
461 }
462
463 impl NameOrNameRef {
464     pub fn text(&self) -> TokenText<'_> {
465         match self {
466             NameOrNameRef::Name(name) => name.text(),
467             NameOrNameRef::NameRef(name_ref) => name_ref.text(),
468         }
469     }
470 }
471
472 impl ast::RecordPatField {
473     pub fn for_field_name_ref(field_name: &ast::NameRef) -> Option<ast::RecordPatField> {
474         let candidate = field_name.syntax().parent().and_then(ast::RecordPatField::cast)?;
475         match candidate.field_name()? {
476             NameOrNameRef::NameRef(name_ref) if name_ref == *field_name => Some(candidate),
477             _ => None,
478         }
479     }
480
481     pub fn for_field_name(field_name: &ast::Name) -> Option<ast::RecordPatField> {
482         let candidate =
483             field_name.syntax().ancestors().nth(2).and_then(ast::RecordPatField::cast)?;
484         match candidate.field_name()? {
485             NameOrNameRef::Name(name) if name == *field_name => Some(candidate),
486             _ => None,
487         }
488     }
489
490     /// Deals with field init shorthand
491     pub fn field_name(&self) -> Option<NameOrNameRef> {
492         if let Some(name_ref) = self.name_ref() {
493             return Some(NameOrNameRef::NameRef(name_ref));
494         }
495         match self.pat() {
496             Some(ast::Pat::IdentPat(pat)) => {
497                 let name = pat.name()?;
498                 Some(NameOrNameRef::Name(name))
499             }
500             Some(ast::Pat::BoxPat(pat)) => match pat.pat() {
501                 Some(ast::Pat::IdentPat(pat)) => {
502                     let name = pat.name()?;
503                     Some(NameOrNameRef::Name(name))
504                 }
505                 _ => None,
506             },
507             _ => None,
508         }
509     }
510 }
511
512 impl ast::Variant {
513     pub fn parent_enum(&self) -> ast::Enum {
514         self.syntax()
515             .parent()
516             .and_then(|it| it.parent())
517             .and_then(ast::Enum::cast)
518             .expect("EnumVariants are always nested in Enums")
519     }
520     pub fn kind(&self) -> StructKind {
521         StructKind::from_node(self)
522     }
523 }
524
525 impl ast::Item {
526     pub fn generic_param_list(&self) -> Option<ast::GenericParamList> {
527         ast::AnyHasGenericParams::cast(self.syntax().clone())?.generic_param_list()
528     }
529 }
530
531 #[derive(Debug, Clone, PartialEq, Eq)]
532 pub enum FieldKind {
533     Name(ast::NameRef),
534     Index(SyntaxToken),
535 }
536
537 impl ast::FieldExpr {
538     pub fn index_token(&self) -> Option<SyntaxToken> {
539         self.syntax
540             .children_with_tokens()
541             // FIXME: Accepting floats here to reject them in validation later
542             .find(|c| c.kind() == SyntaxKind::INT_NUMBER || c.kind() == SyntaxKind::FLOAT_NUMBER)
543             .as_ref()
544             .and_then(SyntaxElement::as_token)
545             .cloned()
546     }
547
548     pub fn field_access(&self) -> Option<FieldKind> {
549         match self.name_ref() {
550             Some(nr) => Some(FieldKind::Name(nr)),
551             None => self.index_token().map(FieldKind::Index),
552         }
553     }
554 }
555
556 pub struct SlicePatComponents {
557     pub prefix: Vec<ast::Pat>,
558     pub slice: Option<ast::Pat>,
559     pub suffix: Vec<ast::Pat>,
560 }
561
562 impl ast::SlicePat {
563     pub fn components(&self) -> SlicePatComponents {
564         let mut args = self.pats().peekable();
565         let prefix = args
566             .peeking_take_while(|p| match p {
567                 ast::Pat::RestPat(_) => false,
568                 ast::Pat::IdentPat(bp) => !matches!(bp.pat(), Some(ast::Pat::RestPat(_))),
569                 ast::Pat::RefPat(rp) => match rp.pat() {
570                     Some(ast::Pat::RestPat(_)) => false,
571                     Some(ast::Pat::IdentPat(bp)) => !matches!(bp.pat(), Some(ast::Pat::RestPat(_))),
572                     _ => true,
573                 },
574                 _ => true,
575             })
576             .collect();
577         let slice = args.next();
578         let suffix = args.collect();
579
580         SlicePatComponents { prefix, slice, suffix }
581     }
582 }
583
584 impl ast::IdentPat {
585     pub fn is_simple_ident(&self) -> bool {
586         self.at_token().is_none()
587             && self.mut_token().is_none()
588             && self.ref_token().is_none()
589             && self.pat().is_none()
590     }
591 }
592
593 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
594 pub enum SelfParamKind {
595     /// self
596     Owned,
597     /// &self
598     Ref,
599     /// &mut self
600     MutRef,
601 }
602
603 impl ast::SelfParam {
604     pub fn kind(&self) -> SelfParamKind {
605         if self.amp_token().is_some() {
606             if self.mut_token().is_some() {
607                 SelfParamKind::MutRef
608             } else {
609                 SelfParamKind::Ref
610             }
611         } else {
612             SelfParamKind::Owned
613         }
614     }
615 }
616
617 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
618 pub enum TypeBoundKind {
619     /// Trait
620     PathType(ast::PathType),
621     /// for<'a> ...
622     ForType(ast::ForType),
623     /// 'a
624     Lifetime(ast::Lifetime),
625 }
626
627 impl ast::TypeBound {
628     pub fn kind(&self) -> TypeBoundKind {
629         if let Some(path_type) = support::children(self.syntax()).next() {
630             TypeBoundKind::PathType(path_type)
631         } else if let Some(for_type) = support::children(self.syntax()).next() {
632             TypeBoundKind::ForType(for_type)
633         } else if let Some(lifetime) = self.lifetime() {
634             TypeBoundKind::Lifetime(lifetime)
635         } else {
636             unreachable!()
637         }
638     }
639 }
640
641 pub enum VisibilityKind {
642     In(ast::Path),
643     PubCrate,
644     PubSuper,
645     PubSelf,
646     Pub,
647 }
648
649 impl ast::Visibility {
650     pub fn kind(&self) -> VisibilityKind {
651         match self.path() {
652             Some(path) => {
653                 if let Some(segment) =
654                     path.as_single_segment().filter(|it| it.coloncolon_token().is_none())
655                 {
656                     if segment.crate_token().is_some() {
657                         return VisibilityKind::PubCrate;
658                     } else if segment.super_token().is_some() {
659                         return VisibilityKind::PubSuper;
660                     } else if segment.self_token().is_some() {
661                         return VisibilityKind::PubSelf;
662                     }
663                 }
664                 VisibilityKind::In(path)
665             }
666             None => VisibilityKind::Pub,
667         }
668     }
669 }
670
671 impl ast::LifetimeParam {
672     pub fn lifetime_bounds(&self) -> impl Iterator<Item = SyntaxToken> {
673         self.syntax()
674             .children_with_tokens()
675             .filter_map(|it| it.into_token())
676             .skip_while(|x| x.kind() != T![:])
677             .filter(|it| it.kind() == T![lifetime_ident])
678     }
679 }
680
681 impl ast::Module {
682     /// Returns the parent ast::Module, this is different than the semantic parent in that this only
683     /// considers parent declarations in the AST
684     pub fn parent(&self) -> Option<ast::Module> {
685         self.syntax().ancestors().nth(2).and_then(ast::Module::cast)
686     }
687 }
688
689 impl ast::RangePat {
690     pub fn start(&self) -> Option<ast::Pat> {
691         self.syntax()
692             .children_with_tokens()
693             .take_while(|it| !(it.kind() == T![..] || it.kind() == T![..=]))
694             .filter_map(|it| it.into_node())
695             .find_map(ast::Pat::cast)
696     }
697
698     pub fn end(&self) -> Option<ast::Pat> {
699         self.syntax()
700             .children_with_tokens()
701             .skip_while(|it| !(it.kind() == T![..] || it.kind() == T![..=]))
702             .filter_map(|it| it.into_node())
703             .find_map(ast::Pat::cast)
704     }
705 }
706
707 impl ast::TokenTree {
708     pub fn token_trees_and_tokens(
709         &self,
710     ) -> impl Iterator<Item = NodeOrToken<ast::TokenTree, SyntaxToken>> {
711         self.syntax().children_with_tokens().filter_map(|not| match not {
712             NodeOrToken::Node(node) => ast::TokenTree::cast(node).map(NodeOrToken::Node),
713             NodeOrToken::Token(t) => Some(NodeOrToken::Token(t)),
714         })
715     }
716
717     pub fn left_delimiter_token(&self) -> Option<SyntaxToken> {
718         self.syntax()
719             .first_child_or_token()?
720             .into_token()
721             .filter(|it| matches!(it.kind(), T!['{'] | T!['('] | T!['[']))
722     }
723
724     pub fn right_delimiter_token(&self) -> Option<SyntaxToken> {
725         self.syntax()
726             .last_child_or_token()?
727             .into_token()
728             .filter(|it| matches!(it.kind(), T!['}'] | T![')'] | T![']']))
729     }
730
731     pub fn parent_meta(&self) -> Option<ast::Meta> {
732         self.syntax().parent().and_then(ast::Meta::cast)
733     }
734 }
735
736 impl ast::Meta {
737     pub fn parent_attr(&self) -> Option<ast::Attr> {
738         self.syntax().parent().and_then(ast::Attr::cast)
739     }
740 }
741
742 impl ast::GenericParamList {
743     pub fn lifetime_params(&self) -> impl Iterator<Item = ast::LifetimeParam> {
744         self.generic_params().filter_map(|param| match param {
745             ast::GenericParam::LifetimeParam(it) => Some(it),
746             ast::GenericParam::TypeParam(_) | ast::GenericParam::ConstParam(_) => None,
747         })
748     }
749     pub fn type_params(&self) -> impl Iterator<Item = ast::TypeParam> {
750         self.generic_params().filter_map(|param| match param {
751             ast::GenericParam::TypeParam(it) => Some(it),
752             ast::GenericParam::LifetimeParam(_) | ast::GenericParam::ConstParam(_) => None,
753         })
754     }
755     pub fn const_params(&self) -> impl Iterator<Item = ast::ConstParam> {
756         self.generic_params().filter_map(|param| match param {
757             ast::GenericParam::ConstParam(it) => Some(it),
758             ast::GenericParam::TypeParam(_) | ast::GenericParam::LifetimeParam(_) => None,
759         })
760     }
761 }
762
763 impl ast::HasLoopBody for ast::ForExpr {
764     fn loop_body(&self) -> Option<ast::BlockExpr> {
765         let mut exprs = support::children(self.syntax());
766         let first = exprs.next();
767         let second = exprs.next();
768         second.or(first)
769     }
770 }
771
772 impl ast::HasAttrs for ast::AnyHasDocComments {}
773
774 impl From<ast::Adt> for ast::Item {
775     fn from(it: ast::Adt) -> Self {
776         match it {
777             ast::Adt::Enum(it) => ast::Item::Enum(it),
778             ast::Adt::Struct(it) => ast::Item::Struct(it),
779             ast::Adt::Union(it) => ast::Item::Union(it),
780         }
781     }
782 }