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