rustc_ast/
visit.rs

1//! AST walker. Each overridden visit method has full control over what
2//! happens with its node, it can do its own traversal of the node's children,
3//! call `visit::walk_*` to apply the default traversal algorithm, or prevent
4//! deeper traversal by doing nothing.
5//!
6//! Note: it is an important invariant that the default visitor walks the body
7//! of a function in "execution order" (more concretely, reverse post-order
8//! with respect to the CFG implied by the AST), meaning that if AST node A may
9//! execute before AST node B, then A is visited first. The borrow checker in
10//! particular relies on this property.
11//!
12//! Note: walking an AST before macro expansion is probably a bad idea. For
13//! instance, a walker looking for item names in a module will miss all of
14//! those that are created by the expansion of a macro.
15
16pub use rustc_ast_ir::visit::VisitorResult;
17pub use rustc_ast_ir::{try_visit, visit_opt, walk_list, walk_visitable_list};
18use rustc_span::source_map::Spanned;
19use rustc_span::{Ident, Span, Symbol};
20use thin_vec::ThinVec;
21
22use crate::ast::*;
23use crate::tokenstream::DelimSpan;
24
25#[derive(Copy, Clone, Debug, PartialEq)]
26pub enum AssocCtxt {
27    Trait,
28    Impl { of_trait: bool },
29}
30
31#[derive(Copy, Clone, Debug, PartialEq)]
32pub enum FnCtxt {
33    Free,
34    Foreign,
35    Assoc(AssocCtxt),
36}
37
38#[derive(Copy, Clone, Debug)]
39pub enum BoundKind {
40    /// Trait bounds in generics bounds and type/trait alias.
41    /// E.g., `<T: Bound>`, `type A: Bound`, or `where T: Bound`.
42    Bound,
43
44    /// Trait bounds in `impl` type.
45    /// E.g., `type Foo = impl Bound1 + Bound2 + Bound3`.
46    Impl,
47
48    /// Trait bounds in trait object type.
49    /// E.g., `dyn Bound1 + Bound2 + Bound3`.
50    TraitObject,
51
52    /// Super traits of a trait.
53    /// E.g., `trait A: B`
54    SuperTraits,
55}
56impl BoundKind {
57    pub fn descr(self) -> &'static str {
58        match self {
59            BoundKind::Bound => "bounds",
60            BoundKind::Impl => "`impl Trait`",
61            BoundKind::TraitObject => "`dyn` trait object bounds",
62            BoundKind::SuperTraits => "supertrait bounds",
63        }
64    }
65}
66
67#[derive(Copy, Clone, Debug)]
68pub enum LifetimeCtxt {
69    /// Appears in a reference type.
70    Ref,
71    /// Appears as a bound on a type or another lifetime.
72    Bound,
73    /// Appears as a generic argument.
74    GenericArg,
75}
76
77pub(crate) trait Visitable<'a, V: Visitor<'a>> {
78    type Extra: Copy;
79
80    #[must_use]
81    fn visit(&'a self, visitor: &mut V, extra: Self::Extra) -> V::Result;
82}
83
84impl<'a, V: Visitor<'a>, T: ?Sized> Visitable<'a, V> for Box<T>
85where
86    T: Visitable<'a, V>,
87{
88    type Extra = T::Extra;
89    fn visit(&'a self, visitor: &mut V, extra: Self::Extra) -> V::Result {
90        (**self).visit(visitor, extra)
91    }
92}
93
94impl<'a, V: Visitor<'a>, T> Visitable<'a, V> for Option<T>
95where
96    T: Visitable<'a, V>,
97{
98    type Extra = T::Extra;
99    fn visit(&'a self, visitor: &mut V, extra: Self::Extra) -> V::Result {
100        if let Some(this) = self {
101            try_visit!(this.visit(visitor, extra));
102        }
103        V::Result::output()
104    }
105}
106
107impl<'a, V: Visitor<'a>, T> Visitable<'a, V> for Spanned<T>
108where
109    T: Visitable<'a, V>,
110{
111    type Extra = T::Extra;
112    fn visit(&'a self, visitor: &mut V, extra: Self::Extra) -> V::Result {
113        let Spanned { span: _, node } = self;
114        node.visit(visitor, extra)
115    }
116}
117
118impl<'a, V: Visitor<'a>, T> Visitable<'a, V> for [T]
119where
120    T: Visitable<'a, V>,
121{
122    type Extra = T::Extra;
123    fn visit(&'a self, visitor: &mut V, extra: Self::Extra) -> V::Result {
124        for item in self {
125            try_visit!(item.visit(visitor, extra));
126        }
127        V::Result::output()
128    }
129}
130
131impl<'a, V: Visitor<'a>, T> Visitable<'a, V> for Vec<T>
132where
133    T: Visitable<'a, V>,
134{
135    type Extra = T::Extra;
136    fn visit(&'a self, visitor: &mut V, extra: Self::Extra) -> V::Result {
137        for item in self {
138            try_visit!(item.visit(visitor, extra));
139        }
140        V::Result::output()
141    }
142}
143
144impl<'a, V: Visitor<'a>, T> Visitable<'a, V> for (T,)
145where
146    T: Visitable<'a, V>,
147{
148    type Extra = T::Extra;
149    fn visit(&'a self, visitor: &mut V, extra: Self::Extra) -> V::Result {
150        self.0.visit(visitor, extra)
151    }
152}
153
154impl<'a, V: Visitor<'a>, T1, T2> Visitable<'a, V> for (T1, T2)
155where
156    T1: Visitable<'a, V, Extra = ()>,
157    T2: Visitable<'a, V, Extra = ()>,
158{
159    type Extra = ();
160    fn visit(&'a self, visitor: &mut V, extra: Self::Extra) -> V::Result {
161        try_visit!(self.0.visit(visitor, extra));
162        try_visit!(self.1.visit(visitor, extra));
163        V::Result::output()
164    }
165}
166
167impl<'a, V: Visitor<'a>, T1, T2, T3> Visitable<'a, V> for (T1, T2, T3)
168where
169    T1: Visitable<'a, V, Extra = ()>,
170    T2: Visitable<'a, V, Extra = ()>,
171    T3: Visitable<'a, V, Extra = ()>,
172{
173    type Extra = ();
174    fn visit(&'a self, visitor: &mut V, extra: Self::Extra) -> V::Result {
175        try_visit!(self.0.visit(visitor, extra));
176        try_visit!(self.1.visit(visitor, extra));
177        try_visit!(self.2.visit(visitor, extra));
178        V::Result::output()
179    }
180}
181
182impl<'a, V: Visitor<'a>, T1, T2, T3, T4> Visitable<'a, V> for (T1, T2, T3, T4)
183where
184    T1: Visitable<'a, V, Extra = ()>,
185    T2: Visitable<'a, V, Extra = ()>,
186    T3: Visitable<'a, V, Extra = ()>,
187    T4: Visitable<'a, V, Extra = ()>,
188{
189    type Extra = ();
190    fn visit(&'a self, visitor: &mut V, extra: Self::Extra) -> V::Result {
191        try_visit!(self.0.visit(visitor, extra));
192        try_visit!(self.1.visit(visitor, extra));
193        try_visit!(self.2.visit(visitor, extra));
194        try_visit!(self.3.visit(visitor, extra));
195        V::Result::output()
196    }
197}
198
199pub(crate) trait Walkable<'a, V: Visitor<'a>> {
200    #[must_use]
201    fn walk_ref(&'a self, visitor: &mut V) -> V::Result;
202}
203
204macro_rules! visit_visitable {
205    ($visitor:expr, $($expr:expr),* $(,)?) => {{
206        $(try_visit!(Visitable::visit($expr, $visitor, ()));)*
207    }};
208}
209
210macro_rules! visit_visitable_with {
211    ($visitor:expr, $expr:expr, $extra:expr $(,)?) => {
212        try_visit!(Visitable::visit($expr, $visitor, $extra))
213    };
214}
215
216macro_rules! walk_walkable {
217    ($visitor:expr, $expr:expr, ) => {
218        Walkable::walk_ref($expr, $visitor)
219    };
220}
221
222macro_rules! impl_visitable {
223    (|&$lt:lifetime $self:ident: $self_ty:ty,
224      $vis:ident: &mut $vis_ty:ident,
225      $extra:ident: $extra_ty:ty| $block:block) => {
226        #[allow(unused_parens, non_local_definitions)]
227        impl<$lt, $vis_ty: Visitor<$lt>> Visitable<$lt, $vis_ty> for $self_ty {
228            type Extra = $extra_ty;
229            fn visit(&$lt $self, $vis: &mut $vis_ty, $extra: Self::Extra) -> V::Result {
230                $block
231            }
232        }
233    };
234}
235
236macro_rules! impl_walkable {
237    ($(<$K:ident: $Kb:ident>)? |&$lt:lifetime $self:ident: $self_ty:ty,
238      $vis:ident: &mut $vis_ty:ident| $block:block) => {
239        #[allow(unused_parens, non_local_definitions)]
240        impl<$($K: $Kb,)? $lt, $vis_ty: Visitor<$lt>> Walkable<$lt, $vis_ty> for $self_ty {
241            fn walk_ref(&$lt $self, $vis: &mut $vis_ty) -> V::Result {
242                $block
243            }
244        }
245    };
246}
247
248macro_rules! impl_visitable_noop {
249    (<$lt:lifetime> $($ty:ty,)*) => {
250        $(
251            impl_visitable!(|&$lt self: $ty, _vis: &mut V, _extra: ()| {
252                V::Result::output()
253            });
254        )*
255    };
256}
257
258macro_rules! impl_visitable_list {
259    (<$lt:lifetime> $($ty:ty,)*) => {
260        $(impl<$lt, V: Visitor<$lt>, T> Visitable<$lt, V> for $ty
261        where
262            &$lt $ty: IntoIterator<Item = &$lt T>,
263            T: $lt + Visitable<$lt, V>,
264        {
265            type Extra = <T as Visitable<$lt, V>>::Extra;
266
267            #[inline]
268            fn visit(&$lt self, visitor: &mut V, extra: Self::Extra) -> V::Result {
269                for i in self {
270                    try_visit!(i.visit(visitor, extra));
271                }
272                V::Result::output()
273            }
274        })*
275    };
276}
277
278macro_rules! impl_visitable_direct {
279    (<$lt:lifetime> $($ty:ty,)*) => {
280        $(impl_visitable!(
281            |&$lt self: $ty, visitor: &mut V, _extra: ()| {
282                Walkable::walk_ref(self, visitor)
283            }
284        );)*
285    };
286}
287
288macro_rules! impl_visitable_calling_walkable {
289    (<$lt:lifetime>
290        $( fn $method:ident($ty:ty $(, $extra_name:ident: $extra_ty:ty)?); )*
291    ) => {
292        $(fn $method(&mut self, node: &$lt $ty $(, $extra_name:$extra_ty)?) -> Self::Result {
293            impl_visitable!(|&$lt self: $ty, visitor: &mut V, extra: ($($extra_ty)?)| {
294                let ($($extra_name)?) = extra;
295                visitor.$method(self $(, $extra_name)?)
296            });
297            walk_walkable!(self, node, )
298        })*
299    };
300}
301
302macro_rules! define_named_walk {
303    ($Visitor:ident<$lt:lifetime>
304        $( pub fn $method:ident($ty:ty); )*
305    ) => {
306        $(pub fn $method<$lt, V: $Visitor<$lt>>(visitor: &mut V, node: &$lt $ty) -> V::Result {
307            walk_walkable!(visitor, node,)
308        })*
309    };
310}
311
312#[macro_export]
313macro_rules! common_visitor_and_walkers {
314    ($(($mut: ident))? $Visitor:ident$(<$lt:lifetime>)?) => {
315        $(${ignore($lt)}
316            #[derive(Copy, Clone)]
317        )?
318        #[derive(Debug)]
319        pub enum FnKind<'a> {
320            /// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`.
321            Fn(FnCtxt, &'a $($mut)? Visibility, &'a $($mut)? Fn),
322
323            /// E.g., `|x, y| body`.
324            Closure(&'a $($mut)? ClosureBinder, &'a $($mut)? Option<CoroutineKind>, &'a $($mut)? Box<FnDecl>, &'a $($mut)? Box<Expr>),
325        }
326
327        impl<'a> FnKind<'a> {
328            pub fn header(&'a $($mut)? self) -> Option<&'a $($mut)? FnHeader> {
329                match *self {
330                    FnKind::Fn(_, _, Fn { sig, .. }) => Some(&$($mut)? sig.header),
331                    FnKind::Closure(..) => None,
332                }
333            }
334
335            pub fn ident(&'a $($mut)? self) -> Option<&'a $($mut)? Ident> {
336                match self {
337                    FnKind::Fn(_, _, Fn { ident, .. }) => Some(ident),
338                    _ => None,
339                }
340            }
341
342            pub fn decl(&'a $($mut)? self) -> &'a $($mut)? FnDecl {
343                match self {
344                    FnKind::Fn(_, _, Fn { sig, .. }) => &$($mut)? sig.decl,
345                    FnKind::Closure(_, _, decl, _) => decl,
346                }
347            }
348
349            pub fn ctxt(&self) -> Option<FnCtxt> {
350                match self {
351                    FnKind::Fn(ctxt, ..) => Some(*ctxt),
352                    FnKind::Closure(..) => None,
353                }
354            }
355        }
356
357        // This macro generates `impl Visitable` and `impl MutVisitable` that do nothing.
358        impl_visitable_noop!(<$($lt)? $($mut)?>
359            AttrId,
360            bool,
361            rustc_span::ByteSymbol,
362            char,
363            crate::token::CommentKind,
364            crate::token::Delimiter,
365            crate::token::Lit,
366            crate::token::LitKind,
367            crate::tokenstream::LazyAttrTokenStream,
368            crate::tokenstream::TokenStream,
369            Movability,
370            Mutability,
371            Result<(), rustc_span::ErrorGuaranteed>,
372            rustc_data_structures::fx::FxHashMap<Symbol, usize>,
373            rustc_span::ErrorGuaranteed,
374            std::borrow::Cow<'_, str>,
375            Symbol,
376            u8,
377            usize,
378        );
379        // `Span` is only a no-op for the non-mutable visitor.
380        $(impl_visitable_noop!(<$lt> Span,);)?
381
382        // This macro generates `impl Visitable` and `impl MutVisitable` that simply iterate over
383        // their contents. We do not use a generic impl for `ThinVec` because we want to allow
384        // custom visits for the `MutVisitor`.
385        impl_visitable_list!(<$($lt)? $($mut)?>
386            ThinVec<AngleBracketedArg>,
387            ThinVec<Attribute>,
388            ThinVec<(Ident, Option<Ident>)>,
389            ThinVec<(NodeId, Path)>,
390            ThinVec<PathSegment>,
391            ThinVec<PreciseCapturingArg>,
392            ThinVec<Box<Pat>>,
393            ThinVec<Box<Ty>>,
394            ThinVec<Box<TyPat>>,
395        );
396
397        // This macro generates `impl Visitable` and `impl MutVisitable` that forward to `Walkable`
398        // or `MutWalkable`. By default, all types that do not have a custom visit method in the
399        // visitor should appear here.
400        impl_visitable_direct!(<$($lt)? $($mut)?>
401            AngleBracketedArg,
402            AngleBracketedArgs,
403            AsmMacro,
404            AssignOpKind,
405            AssocItemConstraintKind,
406            AttrArgs,
407            AttrItem,
408            AttrKind,
409            AttrStyle,
410            FnPtrTy,
411            BindingMode,
412            GenBlockKind,
413            RangeLimits,
414            UnsafeBinderCastKind,
415            BinOpKind,
416            BlockCheckMode,
417            BorrowKind,
418            BoundAsyncness,
419            BoundConstness,
420            BoundPolarity,
421            ByRef,
422            Closure,
423            Const,
424            ConstItem,
425            Defaultness,
426            Delegation,
427            DelegationMac,
428            DelimArgs,
429            DelimSpan,
430            EnumDef,
431            Extern,
432            ForLoopKind,
433            FormatArgPosition,
434            FormatArgsPiece,
435            FormatArgument,
436            FormatArgumentKind,
437            FormatArguments,
438            FormatPlaceholder,
439            GenericParamKind,
440            Impl,
441            ImplPolarity,
442            Inline,
443            InlineAsmOperand,
444            InlineAsmRegOrRegClass,
445            InlineAsmTemplatePiece,
446            IsAuto,
447            LocalKind,
448            MacCallStmt,
449            MacStmtStyle,
450            MatchKind,
451            MethodCall,
452            ModKind,
453            ModSpans,
454            MutTy,
455            NormalAttr,
456            Parens,
457            ParenthesizedArgs,
458            PatFieldsRest,
459            PatKind,
460            RangeEnd,
461            RangeSyntax,
462            Recovered,
463            Safety,
464            StaticItem,
465            StrLit,
466            StrStyle,
467            StructExpr,
468            StructRest,
469            Term,
470            Trait,
471            TraitBoundModifiers,
472            TraitObjectSyntax,
473            TyAlias,
474            TyAliasWhereClause,
475            TyAliasWhereClauses,
476            TyKind,
477            TyPatKind,
478            UnOp,
479            UnsafeBinderTy,
480            UnsafeSource,
481            UseTreeKind,
482            VisibilityKind,
483            WhereBoundPredicate,
484            WhereClause,
485            WhereEqPredicate,
486            WhereRegionPredicate,
487            YieldKind,
488        );
489
490        /// Each method of this trait is a hook to be potentially
491        /// overridden. Each method's default implementation recursively visits
492        /// the substructure of the input via the corresponding `walk` method;
493        #[doc = concat!(" e.g., the `visit_item` method by default calls `visit"$(, "_", stringify!($mut))?, "::walk_item`.")]
494        ///
495        /// If you want to ensure that your code handles every variant
496        /// explicitly, you need to override each method. (And you also need
497        /// to monitor future changes to this trait in case a new method with a
498        /// new default implementation gets introduced.)
499        ///
500        /// Every `walk_*` method uses deconstruction to access fields of structs and
501        /// enums. This will result in a compile error if a field is added, which makes
502        /// it more likely the appropriate visit call will be added for it.
503        pub trait $Visitor<$($lt)?> : Sized $(${ignore($mut)} + MutVisitorResult<Result = ()>)? {
504            $(
505                ${ignore($lt)}
506                /// The result type of the `visit_*` methods. Can be either `()`,
507                /// or `ControlFlow<T>`.
508                type Result: VisitorResult = ();
509            )?
510
511            // Methods in this trait have one of three forms, with the last two forms
512            // only occurring on `MutVisitor`:
513            //
514            //   fn visit_t(&mut self, t: &mut T);                      // common
515            //   fn flat_map_t(&mut self, t: T) -> SmallVec<[T; 1]>;    // rare
516            //   fn filter_map_t(&mut self, t: T) -> Option<T>;         // rarest
517            //
518            // When writing these methods, it is better to use destructuring like this:
519            //
520            //   fn visit_abc(&mut self, ABC { a, b, c: _ }: &mut ABC) {
521            //       visit_a(a);
522            //       visit_b(b);
523            //   }
524            //
525            // than to use field access like this:
526            //
527            //   fn visit_abc(&mut self, abc: &mut ABC) {
528            //       visit_a(&mut abc.a);
529            //       visit_b(&mut abc.b);
530            //       // ignore abc.c
531            //   }
532            //
533            // As well as being more concise, the former is explicit about which fields
534            // are skipped. Furthermore, if a new field is added, the destructuring
535            // version will cause a compile error, which is good. In comparison, the
536            // field access version will continue working and it would be easy to
537            // forget to add handling for it.
538            fn visit_ident(&mut self, Ident { name: _, span }: &$($lt)? $($mut)? Ident) -> Self::Result {
539                impl_visitable!(|&$($lt)? $($mut)? self: Ident, visitor: &mut V, _extra: ()| {
540                    visitor.visit_ident(self)
541                });
542                visit_span(self, span)
543            }
544
545            // This macro defines a custom visit method for each listed type.
546            // It implements `impl Visitable` and `impl MutVisitable` to call those methods on the
547            // visitor.
548            impl_visitable_calling_walkable!(<$($lt)? $($mut)?>
549                fn visit_anon_const(AnonConst);
550                fn visit_arm(Arm);
551                //fn visit_assoc_item(AssocItem, _ctxt: AssocCtxt);
552                fn visit_assoc_item_constraint(AssocItemConstraint);
553                fn visit_attribute(Attribute);
554                fn visit_block(Block);
555                //fn visit_nested_use_tree((UseTree, NodeId));
556                fn visit_capture_by(CaptureBy);
557                fn visit_closure_binder(ClosureBinder);
558                fn visit_contract(FnContract);
559                fn visit_coroutine_kind(CoroutineKind);
560                fn visit_crate(Crate);
561                fn visit_expr(Expr);
562                fn visit_expr_field(ExprField);
563                fn visit_field_def(FieldDef);
564                fn visit_fn_decl(FnDecl);
565                fn visit_fn_header(FnHeader);
566                fn visit_fn_ret_ty(FnRetTy);
567                //fn visit_foreign_item(ForeignItem);
568                fn visit_foreign_mod(ForeignMod);
569                fn visit_format_args(FormatArgs);
570                fn visit_generic_arg(GenericArg);
571                fn visit_generic_args(GenericArgs);
572                fn visit_generic_param(GenericParam);
573                fn visit_generics(Generics);
574                fn visit_inline_asm(InlineAsm);
575                fn visit_inline_asm_sym(InlineAsmSym);
576                //fn visit_item(Item);
577                fn visit_label(Label);
578                fn visit_lifetime(Lifetime, _ctxt: LifetimeCtxt);
579                fn visit_local(Local);
580                fn visit_mac_call(MacCall);
581                fn visit_macro_def(MacroDef);
582                fn visit_param_bound(GenericBound, _ctxt: BoundKind);
583                fn visit_param(Param);
584                fn visit_pat_field(PatField);
585                fn visit_path(Path);
586                fn visit_path_segment(PathSegment);
587                fn visit_pat(Pat);
588                fn visit_poly_trait_ref(PolyTraitRef);
589                fn visit_precise_capturing_arg(PreciseCapturingArg);
590                fn visit_qself(QSelf);
591                fn visit_trait_ref(TraitRef);
592                fn visit_ty_pat(TyPat);
593                fn visit_ty(Ty);
594                fn visit_use_tree(UseTree);
595                fn visit_variant_data(VariantData);
596                fn visit_variant(Variant);
597                fn visit_vis(Visibility);
598                fn visit_where_predicate_kind(WherePredicateKind);
599                fn visit_where_predicate(WherePredicate);
600            );
601
602            // We want `Visitor` to take the `NodeId` by value.
603            fn visit_id(&mut self, _id: $(&$mut)? NodeId) -> Self::Result {
604                $(impl_visitable!(
605                    |&$lt self: NodeId, visitor: &mut V, _extra: ()| {
606                        visitor.visit_id(*self)
607                    }
608                );)?
609                $(impl_visitable!(
610                    |&$mut self: NodeId, visitor: &mut V, _extra: ()| {
611                        visitor.visit_id(self)
612                    }
613                );)?
614                Self::Result::output()
615            }
616
617            /// This method is a hack to workaround unstable of `stmt_expr_attributes`.
618            /// It can be removed once that feature is stabilized.
619            fn visit_method_receiver_expr(&mut self, ex: &$($lt)? $($mut)? Expr) -> Self::Result {
620                self.visit_expr(ex)
621            }
622
623            fn visit_item(&mut self, item: &$($lt)? $($mut)? Item) -> Self::Result {
624                impl_visitable!(|&$($lt)? $($mut)? self: Item, vis: &mut V, _extra: ()| {
625                    vis.visit_item(self)
626                });
627                walk_item(self, item)
628            }
629
630            fn visit_foreign_item(&mut self, item: &$($lt)? $($mut)? ForeignItem) -> Self::Result {
631                impl_visitable!(|&$($lt)? $($mut)? self: ForeignItem, vis: &mut V, _extra: ()| {
632                    vis.visit_foreign_item(self)
633                });
634                walk_item(self, item)
635            }
636
637            fn visit_assoc_item(&mut self, item: &$($lt)? $($mut)? AssocItem, ctxt: AssocCtxt) -> Self::Result {
638                impl_visitable!(|&$($lt)? $($mut)? self: AssocItem, vis: &mut V, ctxt: AssocCtxt| {
639                    vis.visit_assoc_item(self, ctxt)
640                });
641                walk_assoc_item(self, item, ctxt)
642            }
643
644            // for `MutVisitor`: `Span` and `NodeId` are mutated at the caller site.
645            fn visit_fn(
646                &mut self,
647                fk: FnKind<$($lt)? $(${ignore($mut)} '_)?>,
648                _: Span,
649                _: NodeId
650            ) -> Self::Result {
651                walk_fn(self, fk)
652            }
653
654            // (non-mut) `Visitor`-only methods
655            $(
656                fn visit_stmt(&mut self, s: &$lt Stmt) -> Self::Result {
657                    walk_stmt(self, s)
658                }
659
660                fn visit_nested_use_tree(&mut self, use_tree: &$lt UseTree, id: NodeId) -> Self::Result {
661                    try_visit!(self.visit_id(id));
662                    self.visit_use_tree(use_tree)
663                }
664            )?
665
666            // `MutVisitor`-only methods
667            $(
668                // Span visiting is no longer used, but we keep it for now,
669                // in case it's needed for something like #127241.
670                #[inline]
671                fn visit_span(&mut self, _sp: &$mut Span) {
672                    impl_visitable!(|&mut self: Span, visitor: &mut V, _extra: ()| {
673                        visitor.visit_span(self)
674                    });
675                    // Do nothing.
676                }
677
678                fn flat_map_foreign_item(&mut self, ni: Box<ForeignItem>) -> SmallVec<[Box<ForeignItem>; 1]> {
679                    walk_flat_map_foreign_item(self, ni)
680                }
681
682                fn flat_map_item(&mut self, i: Box<Item>) -> SmallVec<[Box<Item>; 1]> {
683                    walk_flat_map_item(self, i)
684                }
685
686                fn flat_map_field_def(&mut self, fd: FieldDef) -> SmallVec<[FieldDef; 1]> {
687                    walk_flat_map_field_def(self, fd)
688                }
689
690                fn flat_map_assoc_item(
691                    &mut self,
692                    i: Box<AssocItem>,
693                    ctxt: AssocCtxt,
694                ) -> SmallVec<[Box<AssocItem>; 1]> {
695                    walk_flat_map_assoc_item(self, i, ctxt)
696                }
697
698                fn flat_map_stmt(&mut self, s: Stmt) -> SmallVec<[Stmt; 1]> {
699                    walk_flat_map_stmt(self, s)
700                }
701
702                fn flat_map_arm(&mut self, arm: Arm) -> SmallVec<[Arm; 1]> {
703                    walk_flat_map_arm(self, arm)
704                }
705
706                fn filter_map_expr(&mut self, e: Box<Expr>) -> Option<Box<Expr>> {
707                    walk_filter_map_expr(self, e)
708                }
709
710                fn flat_map_variant(&mut self, v: Variant) -> SmallVec<[Variant; 1]> {
711                    walk_flat_map_variant(self, v)
712                }
713
714                fn flat_map_param(&mut self, param: Param) -> SmallVec<[Param; 1]> {
715                    walk_flat_map_param(self, param)
716                }
717
718                fn flat_map_generic_param(&mut self, param: GenericParam) -> SmallVec<[GenericParam; 1]> {
719                    walk_flat_map_generic_param(self, param)
720                }
721
722                fn flat_map_expr_field(&mut self, f: ExprField) -> SmallVec<[ExprField; 1]> {
723                    walk_flat_map_expr_field(self, f)
724                }
725
726                fn flat_map_where_predicate(
727                    &mut self,
728                    where_predicate: WherePredicate,
729                ) -> SmallVec<[WherePredicate; 1]> {
730                    walk_flat_map_where_predicate(self, where_predicate)
731                }
732
733                fn flat_map_pat_field(&mut self, fp: PatField) -> SmallVec<[PatField; 1]> {
734                    walk_flat_map_pat_field(self, fp)
735                }
736            )?
737        }
738
739        pub trait WalkItemKind {
740            type Ctxt;
741            fn walk<$($lt,)? V: $Visitor$(<$lt>)?>(
742                &$($lt)? $($mut)? self,
743                span: Span,
744                id: NodeId,
745                visibility: &$($lt)? $($mut)? Visibility,
746                ctxt: Self::Ctxt,
747                vis: &mut V,
748            ) -> V::Result;
749        }
750
751        // this is only used by the MutVisitor. We include this symmetry here to make writing other functions easier
752        $(${ignore($lt)}
753            #[expect(unused, rustc::pass_by_value)]
754            #[inline]
755        )?
756        fn visit_span<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, span: &$($lt)? $($mut)? Span) -> V::Result {
757            $(${ignore($mut)} vis.visit_span(span))?;
758            V::Result::output()
759        }
760
761        $(impl_visitable!(|&$lt self: ThinVec<(UseTree, NodeId)>, vis: &mut V, _extra: ()| {
762            for (nested_tree, nested_id) in self {
763                try_visit!(vis.visit_nested_use_tree(nested_tree, *nested_id));
764            }
765            V::Result::output()
766        });)?
767        $(impl_visitable_list!(<$mut> ThinVec<(UseTree, NodeId)>,);)?
768
769        fn walk_item_inner<$($lt,)? K: WalkItemKind, V: $Visitor$(<$lt>)?>(
770            visitor: &mut V,
771            item: &$($mut)? $($lt)? Item<K>,
772            ctxt: K::Ctxt,
773        ) -> V::Result {
774            let Item { attrs, id, kind, vis, span, tokens: _ } = item;
775            visit_visitable!($($mut)? visitor, id, attrs, vis);
776            try_visit!(kind.walk(*span, *id, vis, ctxt, visitor));
777            visit_visitable!($($mut)? visitor, span);
778            V::Result::output()
779        }
780
781        // Do not implement `Walkable`/`MutWalkable` for *Item to avoid confusion.
782        pub fn walk_item<$($lt,)? K: WalkItemKind<Ctxt = ()>, V: $Visitor$(<$lt>)?>(
783            visitor: &mut V,
784            item: &$($mut)? $($lt)? Item<K>,
785        ) -> V::Result {
786            walk_item_inner(visitor, item, ())
787        }
788
789        // Do not implement `Walkable`/`MutWalkable` for *Item to avoid confusion.
790        pub fn walk_assoc_item<$($lt,)? K: WalkItemKind<Ctxt = AssocCtxt>, V: $Visitor$(<$lt>)?>(
791            visitor: &mut V,
792            item: &$($mut)? $($lt)? Item<K>,
793            ctxt: AssocCtxt,
794        ) -> V::Result {
795            walk_item_inner(visitor, item, ctxt)
796        }
797
798        impl WalkItemKind for ItemKind {
799            type Ctxt = ();
800            fn walk<$($lt,)? V: $Visitor$(<$lt>)?>(
801                &$($lt)? $($mut)? self,
802                span: Span,
803                id: NodeId,
804                visibility: &$($lt)? $($mut)? Visibility,
805                _ctxt: Self::Ctxt,
806                vis: &mut V,
807            ) -> V::Result {
808                match self {
809                    ItemKind::Fn(func) => {
810                        let kind = FnKind::Fn(FnCtxt::Free, visibility, &$($mut)? *func);
811                        try_visit!(vis.visit_fn(kind, span, id));
812                    }
813                    ItemKind::ExternCrate(orig_name, ident) =>
814                        visit_visitable!($($mut)? vis, orig_name, ident),
815                    ItemKind::Use(use_tree) =>
816                        visit_visitable!($($mut)? vis, use_tree),
817                    ItemKind::Static(item) =>
818                        visit_visitable!($($mut)? vis, item),
819                    ItemKind::Const(item) =>
820                        visit_visitable!($($mut)? vis, item),
821                    ItemKind::Mod(safety, ident, mod_kind) =>
822                        visit_visitable!($($mut)? vis, safety, ident, mod_kind),
823                    ItemKind::ForeignMod(nm) =>
824                        visit_visitable!($($mut)? vis, nm),
825                    ItemKind::GlobalAsm(asm) =>
826                        visit_visitable!($($mut)? vis, asm),
827                    ItemKind::TyAlias(ty_alias) =>
828                        visit_visitable!($($mut)? vis, ty_alias),
829                    ItemKind::Enum(ident, generics, enum_definition) =>
830                        visit_visitable!($($mut)? vis, ident, generics, enum_definition),
831                    ItemKind::Struct(ident, generics, variant_data)
832                    | ItemKind::Union(ident, generics, variant_data) =>
833                        visit_visitable!($($mut)? vis, ident, generics, variant_data),
834                    ItemKind::Impl(impl_) =>
835                        visit_visitable!($($mut)? vis, impl_),
836                    ItemKind::Trait(trait_) =>
837                        visit_visitable!($($mut)? vis, trait_),
838                    ItemKind::TraitAlias(ident, generics, bounds) => {
839                        visit_visitable!($($mut)? vis, ident, generics);
840                        visit_visitable_with!($($mut)? vis, bounds, BoundKind::Bound)
841                    }
842                    ItemKind::MacCall(m) =>
843                        visit_visitable!($($mut)? vis, m),
844                    ItemKind::MacroDef(ident, def) =>
845                        visit_visitable!($($mut)? vis, ident, def),
846                    ItemKind::Delegation(delegation) =>
847                        visit_visitable!($($mut)? vis, delegation),
848                    ItemKind::DelegationMac(dm) =>
849                        visit_visitable!($($mut)? vis, dm),
850                }
851                V::Result::output()
852            }
853        }
854
855        impl WalkItemKind for AssocItemKind {
856            type Ctxt = AssocCtxt;
857            fn walk<$($lt,)? V: $Visitor$(<$lt>)?>(
858                &$($lt)? $($mut)? self,
859                span: Span,
860                id: NodeId,
861                visibility: &$($lt)? $($mut)? Visibility,
862                ctxt: Self::Ctxt,
863                vis: &mut V,
864            ) -> V::Result {
865                match self {
866                    AssocItemKind::Const(item) =>
867                        visit_visitable!($($mut)? vis, item),
868                    AssocItemKind::Fn(func) => {
869                        let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), visibility, &$($mut)? *func);
870                        try_visit!(vis.visit_fn(kind, span, id))
871                    }
872                    AssocItemKind::Type(alias) =>
873                        visit_visitable!($($mut)? vis, alias),
874                    AssocItemKind::MacCall(mac) =>
875                        visit_visitable!($($mut)? vis, mac),
876                    AssocItemKind::Delegation(delegation) =>
877                        visit_visitable!($($mut)? vis, delegation),
878                    AssocItemKind::DelegationMac(dm) =>
879                        visit_visitable!($($mut)? vis, dm),
880                }
881                V::Result::output()
882            }
883        }
884
885        impl WalkItemKind for ForeignItemKind {
886            type Ctxt = ();
887            fn walk<$($lt,)? V: $Visitor$(<$lt>)?>(
888                &$($lt)? $($mut)? self,
889                span: Span,
890                id: NodeId,
891                visibility: &$($lt)? $($mut)? Visibility,
892                _ctxt: Self::Ctxt,
893                vis: &mut V,
894            ) -> V::Result {
895                match self {
896                    ForeignItemKind::Static(item) =>
897                        visit_visitable!($($mut)? vis, item),
898                    ForeignItemKind::Fn(func) => {
899                        let kind = FnKind::Fn(FnCtxt::Foreign, visibility, &$($mut)?*func);
900                        try_visit!(vis.visit_fn(kind, span, id))
901                    }
902                    ForeignItemKind::TyAlias(alias) =>
903                        visit_visitable!($($mut)? vis, alias),
904                    ForeignItemKind::MacCall(mac) =>
905                        visit_visitable!($($mut)? vis, mac),
906                }
907                V::Result::output()
908            }
909        }
910
911        pub fn walk_fn<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, kind: FnKind<$($lt)? $(${ignore($mut)} '_)?>) -> V::Result {
912            match kind {
913                FnKind::Fn(
914                    _ctxt,
915                    // Visibility is visited as a part of the item.
916                    _vis,
917                    Fn { defaultness, ident, sig, generics, contract, body, define_opaque },
918                ) => {
919                    let FnSig { header, decl, span } = sig;
920                    visit_visitable!($($mut)? vis,
921                        defaultness, ident, header, generics, decl,
922                        contract, body, span, define_opaque
923                    )
924                }
925                FnKind::Closure(binder, coroutine_kind, decl, body) =>
926                    visit_visitable!($($mut)? vis, binder, coroutine_kind, decl, body),
927            }
928            V::Result::output()
929        }
930
931        impl_walkable!(|&$($mut)? $($lt)? self: Impl, vis: &mut V| {
932            let Impl { generics, of_trait, self_ty, items } = self;
933            try_visit!(vis.visit_generics(generics));
934            if let Some(box of_trait) = of_trait {
935                let TraitImplHeader { defaultness, safety, constness, polarity, trait_ref } = of_trait;
936                visit_visitable!($($mut)? vis, defaultness, safety, constness, polarity, trait_ref);
937            }
938            try_visit!(vis.visit_ty(self_ty));
939            visit_visitable_with!($($mut)? vis, items, AssocCtxt::Impl { of_trait: of_trait.is_some() });
940            V::Result::output()
941        });
942
943        // Special case to call `visit_method_receiver_expr`.
944        impl_walkable!(|&$($mut)? $($lt)? self: MethodCall, vis: &mut V| {
945            let MethodCall { seg, receiver, args, span } = self;
946            try_visit!(vis.visit_method_receiver_expr(receiver));
947            visit_visitable!($($mut)? vis, seg, args, span);
948            V::Result::output()
949        });
950
951        impl_walkable!(|&$($mut)? $($lt)? self: Expr, vis: &mut V| {
952            let Expr { id, kind, span, attrs, tokens: _ } = self;
953            visit_visitable!($($mut)? vis, id, attrs);
954            match kind {
955                ExprKind::Array(exprs) =>
956                    visit_visitable!($($mut)? vis, exprs),
957                ExprKind::ConstBlock(anon_const) =>
958                    visit_visitable!($($mut)? vis, anon_const),
959                ExprKind::Repeat(element, count) =>
960                    visit_visitable!($($mut)? vis, element, count),
961                ExprKind::Struct(se) =>
962                    visit_visitable!($($mut)? vis, se),
963                ExprKind::Tup(exprs) =>
964                    visit_visitable!($($mut)? vis, exprs),
965                ExprKind::Call(callee_expression, arguments) =>
966                    visit_visitable!($($mut)? vis, callee_expression, arguments),
967                ExprKind::MethodCall(mc) =>
968                    visit_visitable!($($mut)? vis, mc),
969                ExprKind::Binary(op, lhs, rhs) =>
970                    visit_visitable!($($mut)? vis, op, lhs, rhs),
971                ExprKind::AddrOf(kind, mutbl, subexpression) =>
972                    visit_visitable!($($mut)? vis, kind, mutbl, subexpression),
973                ExprKind::Unary(op, subexpression) =>
974                    visit_visitable!($($mut)? vis, op, subexpression),
975                ExprKind::Cast(subexpression, typ) | ExprKind::Type(subexpression, typ) =>
976                    visit_visitable!($($mut)? vis, subexpression, typ),
977                ExprKind::Let(pat, expr, span, _recovered) =>
978                    visit_visitable!($($mut)? vis, pat, expr, span),
979                ExprKind::If(head_expression, if_block, optional_else) =>
980                    visit_visitable!($($mut)? vis, head_expression, if_block, optional_else),
981                ExprKind::While(subexpression, block, opt_label) =>
982                    visit_visitable!($($mut)? vis, subexpression, block, opt_label),
983                ExprKind::ForLoop { pat, iter, body, label, kind } =>
984                    visit_visitable!($($mut)? vis, pat, iter, body, label, kind),
985                ExprKind::Loop(block, opt_label, span) =>
986                    visit_visitable!($($mut)? vis, block, opt_label, span),
987                ExprKind::Match(subexpression, arms, kind) =>
988                    visit_visitable!($($mut)? vis, subexpression, arms, kind),
989                ExprKind::Closure(box Closure {
990                    binder,
991                    capture_clause,
992                    coroutine_kind,
993                    constness,
994                    movability,
995                    fn_decl,
996                    body,
997                    fn_decl_span,
998                    fn_arg_span,
999                }) => {
1000                    visit_visitable!($($mut)? vis, constness, movability, capture_clause);
1001                    let kind = FnKind::Closure(binder, coroutine_kind, fn_decl, body);
1002                    try_visit!(vis.visit_fn(kind, *span, *id));
1003                    visit_visitable!($($mut)? vis, fn_decl_span, fn_arg_span);
1004                }
1005                ExprKind::Block(block, opt_label) =>
1006                    visit_visitable!($($mut)? vis, block, opt_label),
1007                ExprKind::Gen(capt, body, kind, decl_span) =>
1008                    visit_visitable!($($mut)? vis, capt, body, kind, decl_span),
1009                ExprKind::Await(expr, span) | ExprKind::Use(expr, span) =>
1010                    visit_visitable!($($mut)? vis, expr, span),
1011                ExprKind::Assign(lhs, rhs, span) =>
1012                    visit_visitable!($($mut)? vis, lhs, rhs, span),
1013                ExprKind::AssignOp(op, lhs, rhs) =>
1014                    visit_visitable!($($mut)? vis, op, lhs, rhs),
1015                ExprKind::Field(subexpression, ident) =>
1016                    visit_visitable!($($mut)? vis, subexpression, ident),
1017                ExprKind::Index(main_expression, index_expression, span) =>
1018                    visit_visitable!($($mut)? vis, main_expression, index_expression, span),
1019                ExprKind::Range(start, end, limit) =>
1020                    visit_visitable!($($mut)? vis, start, end, limit),
1021                ExprKind::Underscore => {}
1022                ExprKind::Path(maybe_qself, path) =>
1023                    visit_visitable!($($mut)? vis, maybe_qself, path),
1024                ExprKind::Break(opt_label, opt_expr) =>
1025                    visit_visitable!($($mut)? vis, opt_label, opt_expr),
1026                ExprKind::Continue(opt_label) =>
1027                    visit_visitable!($($mut)? vis, opt_label),
1028                ExprKind::Ret(optional_expression) | ExprKind::Yeet(optional_expression) =>
1029                    visit_visitable!($($mut)? vis, optional_expression),
1030                ExprKind::Become(expr) =>
1031                    visit_visitable!($($mut)? vis, expr),
1032                ExprKind::MacCall(mac) =>
1033                    visit_visitable!($($mut)? vis, mac),
1034                ExprKind::Paren(subexpression) =>
1035                    visit_visitable!($($mut)? vis, subexpression),
1036                ExprKind::InlineAsm(asm) =>
1037                    visit_visitable!($($mut)? vis, asm),
1038                ExprKind::FormatArgs(f) =>
1039                    visit_visitable!($($mut)? vis, f),
1040                ExprKind::OffsetOf(container, fields) =>
1041                    visit_visitable!($($mut)? vis, container, fields),
1042                ExprKind::Yield(kind) =>
1043                    visit_visitable!($($mut)? vis, kind),
1044                ExprKind::Try(subexpression) =>
1045                    visit_visitable!($($mut)? vis, subexpression),
1046                ExprKind::TryBlock(body) =>
1047                    visit_visitable!($($mut)? vis, body),
1048                ExprKind::Lit(token) =>
1049                    visit_visitable!($($mut)? vis, token),
1050                ExprKind::IncludedBytes(bytes) =>
1051                    visit_visitable!($($mut)? vis, bytes),
1052                ExprKind::UnsafeBinderCast(kind, expr, ty) =>
1053                    visit_visitable!($($mut)? vis, kind, expr, ty),
1054                ExprKind::Err(_guar) => {}
1055                ExprKind::Dummy => {}
1056            }
1057
1058            visit_span(vis, span)
1059        });
1060
1061        define_named_walk!($(($mut))? $Visitor$(<$lt>)?
1062            pub fn walk_anon_const(AnonConst);
1063            pub fn walk_arm(Arm);
1064            //pub fn walk_assoc_item(AssocItem, _ctxt: AssocCtxt);
1065            pub fn walk_assoc_item_constraint(AssocItemConstraint);
1066            pub fn walk_attribute(Attribute);
1067            pub fn walk_block(Block);
1068            //pub fn walk_nested_use_tree((UseTree, NodeId));
1069            pub fn walk_capture_by(CaptureBy);
1070            pub fn walk_closure_binder(ClosureBinder);
1071            pub fn walk_contract(FnContract);
1072            pub fn walk_coroutine_kind(CoroutineKind);
1073            pub fn walk_crate(Crate);
1074            pub fn walk_expr(Expr);
1075            pub fn walk_expr_field(ExprField);
1076            pub fn walk_field_def(FieldDef);
1077            pub fn walk_fn_decl(FnDecl);
1078            pub fn walk_fn_header(FnHeader);
1079            pub fn walk_fn_ret_ty(FnRetTy);
1080            //pub fn walk_foreign_item(ForeignItem);
1081            pub fn walk_foreign_mod(ForeignMod);
1082            pub fn walk_format_args(FormatArgs);
1083            pub fn walk_generic_arg(GenericArg);
1084            pub fn walk_generic_args(GenericArgs);
1085            pub fn walk_generic_param(GenericParam);
1086            pub fn walk_generics(Generics);
1087            pub fn walk_inline_asm(InlineAsm);
1088            pub fn walk_inline_asm_sym(InlineAsmSym);
1089            //pub fn walk_item(Item);
1090            pub fn walk_label(Label);
1091            pub fn walk_lifetime(Lifetime);
1092            pub fn walk_local(Local);
1093            pub fn walk_mac(MacCall);
1094            pub fn walk_macro_def(MacroDef);
1095            pub fn walk_param_bound(GenericBound);
1096            pub fn walk_param(Param);
1097            pub fn walk_pat_field(PatField);
1098            pub fn walk_path(Path);
1099            pub fn walk_path_segment(PathSegment);
1100            pub fn walk_pat(Pat);
1101            pub fn walk_poly_trait_ref(PolyTraitRef);
1102            pub fn walk_precise_capturing_arg(PreciseCapturingArg);
1103            pub fn walk_qself(QSelf);
1104            pub fn walk_trait_ref(TraitRef);
1105            pub fn walk_ty_pat(TyPat);
1106            pub fn walk_ty(Ty);
1107            pub fn walk_use_tree(UseTree);
1108            pub fn walk_variant_data(VariantData);
1109            pub fn walk_variant(Variant);
1110            pub fn walk_vis(Visibility);
1111            pub fn walk_where_predicate_kind(WherePredicateKind);
1112            pub fn walk_where_predicate(WherePredicate);
1113        );
1114    };
1115}
1116
1117common_visitor_and_walkers!(Visitor<'a>);
1118
1119macro_rules! generate_list_visit_fns {
1120    ($($name:ident, $Ty:ty, $visit_fn:ident$(, $param:ident: $ParamTy:ty)*;)+) => {
1121        $(
1122            #[allow(unused_parens)]
1123            impl<'a, V: Visitor<'a>> Visitable<'a, V> for ThinVec<$Ty> {
1124                type Extra = ($($ParamTy),*);
1125
1126                #[inline]
1127                fn visit(
1128                    &'a self,
1129                    visitor: &mut V,
1130                    ($($param),*): Self::Extra,
1131                ) -> V::Result {
1132                    $name(visitor, self $(, $param)*)
1133                }
1134            }
1135
1136            fn $name<'a, V: Visitor<'a>>(
1137                vis: &mut V,
1138                values: &'a ThinVec<$Ty>,
1139                $(
1140                    $param: $ParamTy,
1141                )*
1142            ) -> V::Result {
1143                walk_list!(vis, $visit_fn, values$(,$param)*);
1144                V::Result::output()
1145            }
1146        )+
1147    }
1148}
1149
1150generate_list_visit_fns! {
1151    visit_items, Box<Item>, visit_item;
1152    visit_foreign_items, Box<ForeignItem>, visit_foreign_item;
1153    visit_generic_params, GenericParam, visit_generic_param;
1154    visit_stmts, Stmt, visit_stmt;
1155    visit_exprs, Box<Expr>, visit_expr;
1156    visit_expr_fields, ExprField, visit_expr_field;
1157    visit_pat_fields, PatField, visit_pat_field;
1158    visit_variants, Variant, visit_variant;
1159    visit_assoc_items, Box<AssocItem>, visit_assoc_item, ctxt: AssocCtxt;
1160    visit_where_predicates, WherePredicate, visit_where_predicate;
1161    visit_params, Param, visit_param;
1162    visit_field_defs, FieldDef, visit_field_def;
1163    visit_arms, Arm, visit_arm;
1164}
1165
1166pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) -> V::Result {
1167    let Stmt { id, kind, span: _ } = statement;
1168    try_visit!(visitor.visit_id(*id));
1169    match kind {
1170        StmtKind::Let(local) => try_visit!(visitor.visit_local(local)),
1171        StmtKind::Item(item) => try_visit!(visitor.visit_item(item)),
1172        StmtKind::Expr(expr) | StmtKind::Semi(expr) => try_visit!(visitor.visit_expr(expr)),
1173        StmtKind::Empty => {}
1174        StmtKind::MacCall(mac) => {
1175            let MacCallStmt { mac, attrs, style: _, tokens: _ } = &**mac;
1176            walk_list!(visitor, visit_attribute, attrs);
1177            try_visit!(visitor.visit_mac_call(mac));
1178        }
1179    }
1180    V::Result::output()
1181}