rustc_ast/
mut_visit.rs

1//! A `MutVisitor` represents an AST modification; it accepts an AST piece and
2//! mutates it in place. So, for instance, macro expansion is a `MutVisitor`
3//! that walks over an AST and modifies it.
4//!
5//! Note: using a `MutVisitor` (other than the `MacroExpander` `MutVisitor`) on
6//! an AST before macro expansion is probably a bad idea. For instance,
7//! a `MutVisitor` renaming item names in a module will miss all of those
8//! that are created by the expansion of a macro.
9
10use std::ops::DerefMut;
11use std::panic;
12
13use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
14use rustc_span::source_map::Spanned;
15use rustc_span::{Ident, Span, Symbol};
16use smallvec::{SmallVec, smallvec};
17use thin_vec::ThinVec;
18
19use crate::ast::*;
20use crate::tokenstream::*;
21use crate::visit::{AssocCtxt, BoundKind, FnCtxt, LifetimeCtxt, VisitorResult, try_visit};
22
23mod sealed {
24    use rustc_ast_ir::visit::VisitorResult;
25
26    /// This is for compatibility with the regular `Visitor`.
27    pub trait MutVisitorResult {
28        type Result: VisitorResult;
29    }
30
31    impl<T> MutVisitorResult for T {
32        type Result = ();
33    }
34}
35
36use sealed::MutVisitorResult;
37
38pub(crate) trait MutVisitable<V: MutVisitor> {
39    type Extra: Copy;
40    fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra);
41}
42
43impl<V: MutVisitor, T: ?Sized> MutVisitable<V> for Box<T>
44where
45    T: MutVisitable<V>,
46{
47    type Extra = T::Extra;
48    fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
49        (**self).visit_mut(visitor, extra)
50    }
51}
52
53impl<V: MutVisitor, T> MutVisitable<V> for Option<T>
54where
55    T: MutVisitable<V>,
56{
57    type Extra = T::Extra;
58    fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
59        if let Some(this) = self {
60            this.visit_mut(visitor, extra)
61        }
62    }
63}
64
65impl<V: MutVisitor, T> MutVisitable<V> for Spanned<T>
66where
67    T: MutVisitable<V>,
68{
69    type Extra = T::Extra;
70    fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
71        let Spanned { span, node } = self;
72        span.visit_mut(visitor, ());
73        node.visit_mut(visitor, extra);
74    }
75}
76
77impl<V: MutVisitor, T> MutVisitable<V> for [T]
78where
79    T: MutVisitable<V>,
80{
81    type Extra = T::Extra;
82    fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
83        for item in self {
84            item.visit_mut(visitor, extra);
85        }
86    }
87}
88
89impl<V: MutVisitor, T> MutVisitable<V> for Vec<T>
90where
91    T: MutVisitable<V>,
92{
93    type Extra = T::Extra;
94    fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
95        for item in self {
96            item.visit_mut(visitor, extra);
97        }
98    }
99}
100
101impl<V: MutVisitor, T> MutVisitable<V> for (T,)
102where
103    T: MutVisitable<V>,
104{
105    type Extra = T::Extra;
106    fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
107        self.0.visit_mut(visitor, extra);
108    }
109}
110
111impl<V: MutVisitor, T1, T2> MutVisitable<V> for (T1, T2)
112where
113    T1: MutVisitable<V, Extra = ()>,
114    T2: MutVisitable<V, Extra = ()>,
115{
116    type Extra = ();
117    fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
118        self.0.visit_mut(visitor, extra);
119        self.1.visit_mut(visitor, extra);
120    }
121}
122
123impl<V: MutVisitor, T1, T2, T3> MutVisitable<V> for (T1, T2, T3)
124where
125    T1: MutVisitable<V, Extra = ()>,
126    T2: MutVisitable<V, Extra = ()>,
127    T3: MutVisitable<V, Extra = ()>,
128{
129    type Extra = ();
130    fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
131        self.0.visit_mut(visitor, extra);
132        self.1.visit_mut(visitor, extra);
133        self.2.visit_mut(visitor, extra);
134    }
135}
136
137impl<V: MutVisitor, T1, T2, T3, T4> MutVisitable<V> for (T1, T2, T3, T4)
138where
139    T1: MutVisitable<V, Extra = ()>,
140    T2: MutVisitable<V, Extra = ()>,
141    T3: MutVisitable<V, Extra = ()>,
142    T4: MutVisitable<V, Extra = ()>,
143{
144    type Extra = ();
145    fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
146        self.0.visit_mut(visitor, extra);
147        self.1.visit_mut(visitor, extra);
148        self.2.visit_mut(visitor, extra);
149        self.3.visit_mut(visitor, extra);
150    }
151}
152
153pub trait MutWalkable<V: MutVisitor> {
154    fn walk_mut(&mut self, visitor: &mut V);
155}
156
157macro_rules! visit_visitable {
158    (mut $visitor:expr, $($expr:expr),* $(,)?) => {{
159        $(MutVisitable::visit_mut($expr, $visitor, ());)*
160    }};
161}
162
163macro_rules! visit_visitable_with {
164    (mut $visitor:expr, $expr:expr, $extra:expr $(,)?) => {
165        MutVisitable::visit_mut($expr, $visitor, $extra)
166    };
167}
168
169macro_rules! walk_walkable {
170    ($visitor:expr, $expr:expr, mut) => {
171        MutWalkable::walk_mut($expr, $visitor)
172    };
173}
174
175macro_rules! impl_visitable {
176    (|&mut $self:ident: $self_ty:ty,
177      $vis:ident: &mut $vis_ty:ident,
178      $extra:ident: $extra_ty:ty| $block:block) => {
179        #[allow(unused_parens, non_local_definitions)]
180        impl<$vis_ty: MutVisitor> MutVisitable<$vis_ty> for $self_ty {
181            type Extra = $extra_ty;
182            fn visit_mut(&mut $self, $vis: &mut $vis_ty, $extra: Self::Extra) -> V::Result {
183                $block
184            }
185        }
186    };
187}
188
189macro_rules! impl_walkable {
190    ($(<$K:ident: $Kb:ident>)? |&mut $self:ident: $self_ty:ty,
191      $vis:ident: &mut $vis_ty:ident| $block:block) => {
192        #[allow(unused_parens, non_local_definitions)]
193        impl<$($K: $Kb,)? $vis_ty: MutVisitor> MutWalkable<$vis_ty> for $self_ty {
194            fn walk_mut(&mut $self, $vis: &mut $vis_ty) -> V::Result {
195                $block
196            }
197        }
198    };
199}
200
201macro_rules! impl_visitable_noop {
202    (<mut> $($ty:ty,)*) => {
203        $(
204            impl_visitable!(|&mut self: $ty, _vis: &mut V, _extra: ()| {});
205        )*
206    };
207}
208
209macro_rules! impl_visitable_list {
210    (<mut> $($ty:ty,)*) => {
211        $(impl<V: MutVisitor, T> MutVisitable<V> for $ty
212        where
213            for<'a> &'a mut $ty: IntoIterator<Item = &'a mut T>,
214            T: MutVisitable<V>,
215        {
216            type Extra = <T as MutVisitable<V>>::Extra;
217
218            #[inline]
219            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
220                for i in self {
221                    i.visit_mut(visitor, extra);
222                }
223            }
224        })*
225    }
226}
227
228macro_rules! impl_visitable_direct {
229    (<mut> $($ty:ty,)*) => {
230        $(impl_visitable!(
231            |&mut self: $ty, visitor: &mut V, _extra: ()| {
232                MutWalkable::walk_mut(self, visitor)
233            }
234        );)*
235    }
236}
237
238macro_rules! impl_visitable_calling_walkable {
239    (<mut>
240        $( fn $method:ident($ty:ty $(, $extra_name:ident: $extra_ty:ty)?); )*
241    ) => {
242        $(fn $method(&mut self, node: &mut $ty $(, $extra_name:$extra_ty)?) {
243            impl_visitable!(|&mut self: $ty, visitor: &mut V, extra: ($($extra_ty)?)| {
244                let ($($extra_name)?) = extra;
245                visitor.$method(self $(, $extra_name)?);
246            });
247            walk_walkable!(self, node, mut)
248        })*
249    }
250}
251
252macro_rules! define_named_walk {
253    ((mut) $Visitor:ident
254        $( pub fn $method:ident($ty:ty); )*
255    ) => {
256        $(pub fn $method<V: $Visitor>(visitor: &mut V, node: &mut $ty) {
257            walk_walkable!(visitor, node, mut)
258        })*
259    };
260}
261
262#[allow(unused_parens, non_local_definitions)]
impl<V: MutVisitor> MutVisitable<V> for EiiImpl {
    type Extra = ();
    fn visit_mut(&mut self, visitor: &mut V, _extra: Self::Extra)
        -> V::Result {
        { MutWalkable::walk_mut(self, visitor) }
    }
}
/// Each method of this trait is a hook to be potentially
/// overridden. Each method's default implementation recursively visits
/// the substructure of the input via the corresponding `walk` method;
#[doc =
" e.g., the `visit_item` method by default calls `visit_mut::walk_item`."]
///
/// If you want to ensure that your code handles every variant
/// explicitly, you need to override each method. (And you also need
/// to monitor future changes to this trait in case a new method with a
/// new default implementation gets introduced.)
///
/// Every `walk_*` method uses deconstruction to access fields of structs and
/// enums. This will result in a compile error if a field is added, which makes
/// it more likely the appropriate visit call will be added for it.
pub trait MutVisitor: Sized + MutVisitorResult<Result = ()> {
    fn visit_ident(&mut self, Ident { name: _, span }: &mut Ident)
        -> Self::Result {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for Ident {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, _extra: Self::Extra)
                -> V::Result {
                { visitor.visit_ident(self) }
            }
        }
        visit_span(self, span)
    }
    fn visit_anon_const(&mut self, node: &mut AnonConst) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for AnonConst {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_anon_const(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_arm(&mut self, node: &mut Arm) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for Arm {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_arm(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_assoc_item_constraint(&mut self,
        node: &mut AssocItemConstraint) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for AssocItemConstraint {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_assoc_item_constraint(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_attribute(&mut self, node: &mut Attribute) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for Attribute {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_attribute(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_block(&mut self, node: &mut Block) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for Block {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_block(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_capture_by(&mut self, node: &mut CaptureBy) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for CaptureBy {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_capture_by(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_closure_binder(&mut self, node: &mut ClosureBinder) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for ClosureBinder {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_closure_binder(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_contract(&mut self, node: &mut FnContract) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for FnContract {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_contract(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_coroutine_kind(&mut self, node: &mut CoroutineKind) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for CoroutineKind {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_coroutine_kind(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_crate(&mut self, node: &mut Crate) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for Crate {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_crate(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_expr(&mut self, node: &mut Expr) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for Expr {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_expr(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_expr_field(&mut self, node: &mut ExprField) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for ExprField {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_expr_field(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_field_def(&mut self, node: &mut FieldDef) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for FieldDef {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_field_def(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_fn_decl(&mut self, node: &mut FnDecl) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for FnDecl {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_fn_decl(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_fn_header(&mut self, node: &mut FnHeader) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for FnHeader {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_fn_header(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_fn_ret_ty(&mut self, node: &mut FnRetTy) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for FnRetTy {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_fn_ret_ty(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_foreign_mod(&mut self, node: &mut ForeignMod) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for ForeignMod {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_foreign_mod(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_format_args(&mut self, node: &mut FormatArgs) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for FormatArgs {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_format_args(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_generic_arg(&mut self, node: &mut GenericArg) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for GenericArg {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_generic_arg(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_generic_args(&mut self, node: &mut GenericArgs) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for GenericArgs {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_generic_args(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_generic_param(&mut self, node: &mut GenericParam) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for GenericParam {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_generic_param(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_generics(&mut self, node: &mut Generics) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for Generics {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_generics(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_inline_asm(&mut self, node: &mut InlineAsm) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for InlineAsm {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_inline_asm(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_inline_asm_sym(&mut self, node: &mut InlineAsmSym) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for InlineAsmSym {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_inline_asm_sym(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_label(&mut self, node: &mut Label) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for Label {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_label(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_lifetime(&mut self, node: &mut Lifetime, _ctxt: LifetimeCtxt) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for Lifetime {
            type Extra = (LifetimeCtxt);
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let (_ctxt) = extra; visitor.visit_lifetime(self, _ctxt); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_local(&mut self, node: &mut Local) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for Local {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_local(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_mac_call(&mut self, node: &mut MacCall) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for MacCall {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_mac_call(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_macro_def(&mut self, node: &mut MacroDef) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for MacroDef {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_macro_def(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_param_bound(&mut self, node: &mut GenericBound,
        _ctxt: BoundKind) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for GenericBound {
            type Extra = (BoundKind);
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                {
                    let (_ctxt) = extra;
                    visitor.visit_param_bound(self, _ctxt);
                }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_param(&mut self, node: &mut Param) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for Param {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_param(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_pat_field(&mut self, node: &mut PatField) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for PatField {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_pat_field(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_path(&mut self, node: &mut Path) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for Path {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_path(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_path_segment(&mut self, node: &mut PathSegment) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for PathSegment {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_path_segment(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_pat(&mut self, node: &mut Pat) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for Pat {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_pat(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_poly_trait_ref(&mut self, node: &mut PolyTraitRef) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for PolyTraitRef {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_poly_trait_ref(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_precise_capturing_arg(&mut self,
        node: &mut PreciseCapturingArg) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for PreciseCapturingArg {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_precise_capturing_arg(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_qself(&mut self, node: &mut QSelf) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for QSelf {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_qself(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_trait_ref(&mut self, node: &mut TraitRef) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for TraitRef {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_trait_ref(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_ty_pat(&mut self, node: &mut TyPat) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for TyPat {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_ty_pat(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_ty(&mut self, node: &mut Ty) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for Ty {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_ty(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_use_tree(&mut self, node: &mut UseTree) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for UseTree {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_use_tree(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_variant_data(&mut self, node: &mut VariantData) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for VariantData {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_variant_data(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_variant(&mut self, node: &mut Variant) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for Variant {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_variant(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_vis(&mut self, node: &mut Visibility) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for Visibility {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_vis(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_where_predicate_kind(&mut self, node: &mut WherePredicateKind) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for WherePredicateKind {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_where_predicate_kind(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_where_predicate(&mut self, node: &mut WherePredicate) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for WherePredicate {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra)
                -> V::Result {
                { let () = extra; visitor.visit_where_predicate(self); }
            }
        }
        MutWalkable::walk_mut(node, self)
    }
    fn visit_id(&mut self, _id: &mut NodeId) -> Self::Result {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for NodeId {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, _extra: Self::Extra)
                -> V::Result {
                { visitor.visit_id(self) }
            }
        }
        Self::Result::output()
    }
    /// This method is a hack to workaround unstable of `stmt_expr_attributes`.
    /// It can be removed once that feature is stabilized.
    fn visit_method_receiver_expr(&mut self, ex: &mut Expr) -> Self::Result {
        self.visit_expr(ex)
    }
    fn visit_item(&mut self, item: &mut Item) -> Self::Result {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for Item {
            type Extra = ();
            fn visit_mut(&mut self, vis: &mut V, _extra: Self::Extra)
                -> V::Result {
                { vis.visit_item(self) }
            }
        }
        walk_item(self, item)
    }
    fn visit_foreign_item(&mut self, item: &mut ForeignItem) -> Self::Result {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for ForeignItem {
            type Extra = ();
            fn visit_mut(&mut self, vis: &mut V, _extra: Self::Extra)
                -> V::Result {
                { vis.visit_foreign_item(self) }
            }
        }
        walk_item(self, item)
    }
    fn visit_assoc_item(&mut self, item: &mut AssocItem, ctxt: AssocCtxt)
        -> Self::Result {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for AssocItem {
            type Extra = AssocCtxt;
            fn visit_mut(&mut self, vis: &mut V, ctxt: Self::Extra)
                -> V::Result {
                { vis.visit_assoc_item(self, ctxt) }
            }
        }
        walk_assoc_item(self, item, ctxt)
    }
    fn visit_fn(&mut self, fk: FnKind<'_>, _: &AttrVec, _: Span, _: NodeId)
        -> Self::Result {
        walk_fn(self, fk)
    }
    #[inline]
    fn visit_span(&mut self, _sp: &mut Span) {
        #[allow(unused_parens, non_local_definitions)]
        impl<V: MutVisitor> MutVisitable<V> for Span {
            type Extra = ();
            fn visit_mut(&mut self, visitor: &mut V, _extra: Self::Extra)
                -> V::Result {
                { visitor.visit_span(self) }
            }
        }
    }
    fn flat_map_foreign_item(&mut self, ni: Box<ForeignItem>)
        -> SmallVec<[Box<ForeignItem>; 1]> {
        walk_flat_map_foreign_item(self, ni)
    }
    fn flat_map_item(&mut self, i: Box<Item>) -> SmallVec<[Box<Item>; 1]> {
        walk_flat_map_item(self, i)
    }
    fn flat_map_field_def(&mut self, fd: FieldDef)
        -> SmallVec<[FieldDef; 1]> {
        walk_flat_map_field_def(self, fd)
    }
    fn flat_map_assoc_item(&mut self, i: Box<AssocItem>, ctxt: AssocCtxt)
        -> SmallVec<[Box<AssocItem>; 1]> {
        walk_flat_map_assoc_item(self, i, ctxt)
    }
    fn flat_map_stmt(&mut self, s: Stmt) -> SmallVec<[Stmt; 1]> {
        walk_flat_map_stmt(self, s)
    }
    fn flat_map_arm(&mut self, arm: Arm) -> SmallVec<[Arm; 1]> {
        walk_flat_map_arm(self, arm)
    }
    fn filter_map_expr(&mut self, e: Box<Expr>) -> Option<Box<Expr>> {
        walk_filter_map_expr(self, e)
    }
    fn flat_map_variant(&mut self, v: Variant) -> SmallVec<[Variant; 1]> {
        walk_flat_map_variant(self, v)
    }
    fn flat_map_param(&mut self, param: Param) -> SmallVec<[Param; 1]> {
        walk_flat_map_param(self, param)
    }
    fn flat_map_generic_param(&mut self, param: GenericParam)
        -> SmallVec<[GenericParam; 1]> {
        walk_flat_map_generic_param(self, param)
    }
    fn flat_map_expr_field(&mut self, f: ExprField)
        -> SmallVec<[ExprField; 1]> {
        walk_flat_map_expr_field(self, f)
    }
    fn flat_map_where_predicate(&mut self, where_predicate: WherePredicate)
        -> SmallVec<[WherePredicate; 1]> {
        walk_flat_map_where_predicate(self, where_predicate)
    }
    fn flat_map_pat_field(&mut self, fp: PatField)
        -> SmallVec<[PatField; 1]> {
        walk_flat_map_pat_field(self, fp)
    }
}
pub trait WalkItemKind {
    type Ctxt;
    fn walk<V: MutVisitor>(&mut self, attrs: &AttrVec, span: Span, id: NodeId,
    visibility: &mut Visibility, ctxt: Self::Ctxt, vis: &mut V)
    -> V::Result;
}
fn visit_span<V: MutVisitor>(vis: &mut V, span: &mut Span) -> V::Result {
    vis.visit_span(span);
    V::Result::output()
}
impl<V: MutVisitor, T> MutVisitable<V> for ThinVec<(UseTree, NodeId)> where
    for<'a> &'a mut ThinVec<(UseTree,
    NodeId)>: IntoIterator<Item = &'a mut T>, T: MutVisitable<V> {
    type Extra = <T as MutVisitable<V>>::Extra;
    #[inline]
    fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
        for i in self { i.visit_mut(visitor, extra); }
    }
}
fn walk_item_inner<K: WalkItemKind,
    V: MutVisitor>(visitor: &mut V, item: &mut Item<K>, ctxt: K::Ctxt)
    -> V::Result {
    let Item { attrs, id, kind, vis, span, tokens: _ } = item;
    {
        MutVisitable::visit_mut(id, visitor, ());
        MutVisitable::visit_mut(attrs, visitor, ());
        MutVisitable::visit_mut(vis, visitor, ());
    };
    match ::rustc_ast_ir::visit::VisitorResult::branch(kind.walk(attrs, *span,
                *id, vis, ctxt, visitor)) {
        core::ops::ControlFlow::Continue(()) =>
            (),
            #[allow(unreachable_code)]
            core::ops::ControlFlow::Break(r) => {
            return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
        }
    };
    { MutVisitable::visit_mut(span, visitor, ()); };
    V::Result::output()
}
pub fn walk_item<K: WalkItemKind<Ctxt = ()>,
    V: MutVisitor>(visitor: &mut V, item: &mut Item<K>) -> V::Result {
    walk_item_inner(visitor, item, ())
}
pub fn walk_assoc_item<K: WalkItemKind<Ctxt = AssocCtxt>,
    V: MutVisitor>(visitor: &mut V, item: &mut Item<K>, ctxt: AssocCtxt)
    -> V::Result {
    walk_item_inner(visitor, item, ctxt)
}
impl WalkItemKind for ItemKind {
    type Ctxt = ();
    fn walk<V: MutVisitor>(&mut self, attrs: &AttrVec, span: Span, id: NodeId,
        visibility: &mut Visibility, _ctxt: Self::Ctxt, vis: &mut V)
        -> V::Result {
        match self {
            ItemKind::Fn(func) => {
                let kind = FnKind::Fn(FnCtxt::Free, visibility, &mut *func);
                match ::rustc_ast_ir::visit::VisitorResult::branch(vis.visit_fn(kind,
                            attrs, span, id)) {
                    core::ops::ControlFlow::Continue(()) =>
                        (),
                        #[allow(unreachable_code)]
                        core::ops::ControlFlow::Break(r) => {
                        return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                    }
                };
            }
            ItemKind::ExternCrate(orig_name, ident) => {
                MutVisitable::visit_mut(orig_name, vis, ());
                MutVisitable::visit_mut(ident, vis, ());
            }
            ItemKind::Use(use_tree) => {
                MutVisitable::visit_mut(use_tree, vis, ());
            }
            ItemKind::Static(item) => {
                MutVisitable::visit_mut(item, vis, ());
            }
            ItemKind::Const(item) => {
                MutVisitable::visit_mut(item, vis, ());
            }
            ItemKind::Mod(safety, ident, mod_kind) => {
                MutVisitable::visit_mut(safety, vis, ());
                MutVisitable::visit_mut(ident, vis, ());
                MutVisitable::visit_mut(mod_kind, vis, ());
            }
            ItemKind::ForeignMod(nm) => {
                MutVisitable::visit_mut(nm, vis, ());
            }
            ItemKind::GlobalAsm(asm) => {
                MutVisitable::visit_mut(asm, vis, ());
            }
            ItemKind::TyAlias(ty_alias) => {
                MutVisitable::visit_mut(ty_alias, vis, ());
            }
            ItemKind::Enum(ident, generics, enum_definition) => {
                MutVisitable::visit_mut(ident, vis, ());
                MutVisitable::visit_mut(generics, vis, ());
                MutVisitable::visit_mut(enum_definition, vis, ());
            }
            ItemKind::Struct(ident, generics, variant_data) |
                ItemKind::Union(ident, generics, variant_data) => {
                MutVisitable::visit_mut(ident, vis, ());
                MutVisitable::visit_mut(generics, vis, ());
                MutVisitable::visit_mut(variant_data, vis, ());
            }
            ItemKind::Impl(impl_) => {
                MutVisitable::visit_mut(impl_, vis, ());
            }
            ItemKind::Trait(trait_) => {
                MutVisitable::visit_mut(trait_, vis, ());
            }
            ItemKind::TraitAlias(box TraitAlias {
                constness, ident, generics, bounds }) => {
                {
                    MutVisitable::visit_mut(constness, vis, ());
                    MutVisitable::visit_mut(ident, vis, ());
                    MutVisitable::visit_mut(generics, vis, ());
                };
                MutVisitable::visit_mut(bounds, vis, BoundKind::Bound)
            }
            ItemKind::MacCall(m) => { MutVisitable::visit_mut(m, vis, ()); }
            ItemKind::MacroDef(ident, def) => {
                MutVisitable::visit_mut(ident, vis, ());
                MutVisitable::visit_mut(def, vis, ());
            }
            ItemKind::Delegation(delegation) => {
                MutVisitable::visit_mut(delegation, vis, ());
            }
            ItemKind::DelegationMac(dm) => {
                MutVisitable::visit_mut(dm, vis, ());
            }
        }
        V::Result::output()
    }
}
impl WalkItemKind for AssocItemKind {
    type Ctxt = AssocCtxt;
    fn walk<V: MutVisitor>(&mut self, attrs: &AttrVec, span: Span, id: NodeId,
        visibility: &mut Visibility, ctxt: Self::Ctxt, vis: &mut V)
        -> V::Result {
        match self {
            AssocItemKind::Const(item) => {
                MutVisitable::visit_mut(item, vis, ());
            }
            AssocItemKind::Fn(func) => {
                let kind =
                    FnKind::Fn(FnCtxt::Assoc(ctxt), visibility, &mut *func);
                match ::rustc_ast_ir::visit::VisitorResult::branch(vis.visit_fn(kind,
                            attrs, span, id)) {
                    core::ops::ControlFlow::Continue(()) =>
                        (),
                        #[allow(unreachable_code)]
                        core::ops::ControlFlow::Break(r) => {
                        return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                    }
                }
            }
            AssocItemKind::Type(alias) => {
                MutVisitable::visit_mut(alias, vis, ());
            }
            AssocItemKind::MacCall(mac) => {
                MutVisitable::visit_mut(mac, vis, ());
            }
            AssocItemKind::Delegation(delegation) => {
                MutVisitable::visit_mut(delegation, vis, ());
            }
            AssocItemKind::DelegationMac(dm) => {
                MutVisitable::visit_mut(dm, vis, ());
            }
        }
        V::Result::output()
    }
}
impl WalkItemKind for ForeignItemKind {
    type Ctxt = ();
    fn walk<V: MutVisitor>(&mut self, attrs: &AttrVec, span: Span, id: NodeId,
        visibility: &mut Visibility, _ctxt: Self::Ctxt, vis: &mut V)
        -> V::Result {
        match self {
            ForeignItemKind::Static(item) => {
                MutVisitable::visit_mut(item, vis, ());
            }
            ForeignItemKind::Fn(func) => {
                let kind =
                    FnKind::Fn(FnCtxt::Foreign, visibility, &mut *func);
                match ::rustc_ast_ir::visit::VisitorResult::branch(vis.visit_fn(kind,
                            attrs, span, id)) {
                    core::ops::ControlFlow::Continue(()) =>
                        (),
                        #[allow(unreachable_code)]
                        core::ops::ControlFlow::Break(r) => {
                        return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                    }
                }
            }
            ForeignItemKind::TyAlias(alias) => {
                MutVisitable::visit_mut(alias, vis, ());
            }
            ForeignItemKind::MacCall(mac) => {
                MutVisitable::visit_mut(mac, vis, ());
            }
        }
        V::Result::output()
    }
}
pub fn walk_fn<V: MutVisitor>(vis: &mut V, kind: FnKind<'_>) -> V::Result {
    match kind {
        FnKind::Fn(_ctxt, _vis, Fn {
            defaultness,
            ident,
            sig,
            generics,
            contract,
            body,
            define_opaque,
            eii_impls }) => {
            let FnSig { header, decl, span } = sig;
            {
                MutVisitable::visit_mut(defaultness, vis, ());
                MutVisitable::visit_mut(ident, vis, ());
                MutVisitable::visit_mut(header, vis, ());
                MutVisitable::visit_mut(generics, vis, ());
                MutVisitable::visit_mut(decl, vis, ());
                MutVisitable::visit_mut(contract, vis, ());
                MutVisitable::visit_mut(body, vis, ());
                MutVisitable::visit_mut(span, vis, ());
                MutVisitable::visit_mut(define_opaque, vis, ());
                MutVisitable::visit_mut(eii_impls, vis, ());
            };
        }
        FnKind::Closure(binder, coroutine_kind, decl, body) => {
            MutVisitable::visit_mut(binder, vis, ());
            MutVisitable::visit_mut(coroutine_kind, vis, ());
            MutVisitable::visit_mut(decl, vis, ());
            MutVisitable::visit_mut(body, vis, ());
        }
    }
    V::Result::output()
}
#[allow(unused_parens, non_local_definitions)]
impl<V: MutVisitor> MutWalkable<V> for Impl {
    fn walk_mut(&mut self, vis: &mut V) -> V::Result {
        {
            let Impl { generics, of_trait, self_ty, items, constness: _ } =
                self;
            match ::rustc_ast_ir::visit::VisitorResult::branch(vis.visit_generics(generics))
                {
                core::ops::ControlFlow::Continue(()) =>
                    (),
                    #[allow(unreachable_code)]
                    core::ops::ControlFlow::Break(r) => {
                    return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                }
            };
            if let Some(box of_trait) = of_trait {
                let TraitImplHeader { defaultness, safety, polarity, trait_ref
                        } = of_trait;
                {
                    MutVisitable::visit_mut(defaultness, vis, ());
                    MutVisitable::visit_mut(safety, vis, ());
                    MutVisitable::visit_mut(polarity, vis, ());
                    MutVisitable::visit_mut(trait_ref, vis, ());
                };
            }
            match ::rustc_ast_ir::visit::VisitorResult::branch(vis.visit_ty(self_ty))
                {
                core::ops::ControlFlow::Continue(()) =>
                    (),
                    #[allow(unreachable_code)]
                    core::ops::ControlFlow::Break(r) => {
                    return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                }
            };
            MutVisitable::visit_mut(items, vis,
                AssocCtxt::Impl { of_trait: of_trait.is_some() });
            V::Result::output()
        }
    }
}
#[allow(unused_parens, non_local_definitions)]
impl<V: MutVisitor> MutWalkable<V> for MethodCall {
    fn walk_mut(&mut self, vis: &mut V) -> V::Result {
        {
            let MethodCall { seg, receiver, args, span } = self;
            match ::rustc_ast_ir::visit::VisitorResult::branch(vis.visit_method_receiver_expr(receiver))
                {
                core::ops::ControlFlow::Continue(()) =>
                    (),
                    #[allow(unreachable_code)]
                    core::ops::ControlFlow::Break(r) => {
                    return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                }
            };
            {
                MutVisitable::visit_mut(seg, vis, ());
                MutVisitable::visit_mut(args, vis, ());
                MutVisitable::visit_mut(span, vis, ());
            };
            V::Result::output()
        }
    }
}
#[allow(unused_parens, non_local_definitions)]
impl<V: MutVisitor> MutWalkable<V> for Expr {
    fn walk_mut(&mut self, vis: &mut V) -> V::Result {
        {
            let Expr { id, kind, span, attrs, tokens: _ } = self;
            {
                MutVisitable::visit_mut(id, vis, ());
                MutVisitable::visit_mut(attrs, vis, ());
            };
            match kind {
                ExprKind::Array(exprs) => {
                    MutVisitable::visit_mut(exprs, vis, ());
                }
                ExprKind::ConstBlock(anon_const) => {
                    MutVisitable::visit_mut(anon_const, vis, ());
                }
                ExprKind::Repeat(element, count) => {
                    MutVisitable::visit_mut(element, vis, ());
                    MutVisitable::visit_mut(count, vis, ());
                }
                ExprKind::Struct(se) => {
                    MutVisitable::visit_mut(se, vis, ());
                }
                ExprKind::Tup(exprs) => {
                    MutVisitable::visit_mut(exprs, vis, ());
                }
                ExprKind::Call(callee_expression, arguments) => {
                    MutVisitable::visit_mut(callee_expression, vis, ());
                    MutVisitable::visit_mut(arguments, vis, ());
                }
                ExprKind::MethodCall(mc) => {
                    MutVisitable::visit_mut(mc, vis, ());
                }
                ExprKind::Binary(op, lhs, rhs) => {
                    MutVisitable::visit_mut(op, vis, ());
                    MutVisitable::visit_mut(lhs, vis, ());
                    MutVisitable::visit_mut(rhs, vis, ());
                }
                ExprKind::AddrOf(kind, mutbl, subexpression) => {
                    MutVisitable::visit_mut(kind, vis, ());
                    MutVisitable::visit_mut(mutbl, vis, ());
                    MutVisitable::visit_mut(subexpression, vis, ());
                }
                ExprKind::Unary(op, subexpression) => {
                    MutVisitable::visit_mut(op, vis, ());
                    MutVisitable::visit_mut(subexpression, vis, ());
                }
                ExprKind::Cast(subexpression, typ) |
                    ExprKind::Type(subexpression, typ) => {
                    MutVisitable::visit_mut(subexpression, vis, ());
                    MutVisitable::visit_mut(typ, vis, ());
                }
                ExprKind::Let(pat, expr, span, _recovered) => {
                    MutVisitable::visit_mut(pat, vis, ());
                    MutVisitable::visit_mut(expr, vis, ());
                    MutVisitable::visit_mut(span, vis, ());
                }
                ExprKind::If(head_expression, if_block, optional_else) => {
                    MutVisitable::visit_mut(head_expression, vis, ());
                    MutVisitable::visit_mut(if_block, vis, ());
                    MutVisitable::visit_mut(optional_else, vis, ());
                }
                ExprKind::While(subexpression, block, opt_label) => {
                    MutVisitable::visit_mut(subexpression, vis, ());
                    MutVisitable::visit_mut(block, vis, ());
                    MutVisitable::visit_mut(opt_label, vis, ());
                }
                ExprKind::ForLoop { pat, iter, body, label, kind } => {
                    MutVisitable::visit_mut(pat, vis, ());
                    MutVisitable::visit_mut(iter, vis, ());
                    MutVisitable::visit_mut(body, vis, ());
                    MutVisitable::visit_mut(label, vis, ());
                    MutVisitable::visit_mut(kind, vis, ());
                }
                ExprKind::Loop(block, opt_label, span) => {
                    MutVisitable::visit_mut(block, vis, ());
                    MutVisitable::visit_mut(opt_label, vis, ());
                    MutVisitable::visit_mut(span, vis, ());
                }
                ExprKind::Match(subexpression, arms, kind) => {
                    MutVisitable::visit_mut(subexpression, vis, ());
                    MutVisitable::visit_mut(arms, vis, ());
                    MutVisitable::visit_mut(kind, vis, ());
                }
                ExprKind::Closure(box Closure {
                    binder,
                    capture_clause,
                    coroutine_kind,
                    constness,
                    movability,
                    fn_decl,
                    body,
                    fn_decl_span,
                    fn_arg_span }) => {
                    {
                        MutVisitable::visit_mut(constness, vis, ());
                        MutVisitable::visit_mut(movability, vis, ());
                        MutVisitable::visit_mut(capture_clause, vis, ());
                    };
                    let kind =
                        FnKind::Closure(binder, coroutine_kind, fn_decl, body);
                    match ::rustc_ast_ir::visit::VisitorResult::branch(vis.visit_fn(kind,
                                attrs, *span, *id)) {
                        core::ops::ControlFlow::Continue(()) =>
                            (),
                            #[allow(unreachable_code)]
                            core::ops::ControlFlow::Break(r) => {
                            return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                        }
                    };
                    {
                        MutVisitable::visit_mut(fn_decl_span, vis, ());
                        MutVisitable::visit_mut(fn_arg_span, vis, ());
                    };
                }
                ExprKind::Block(block, opt_label) => {
                    MutVisitable::visit_mut(block, vis, ());
                    MutVisitable::visit_mut(opt_label, vis, ());
                }
                ExprKind::Gen(capt, body, kind, decl_span) => {
                    MutVisitable::visit_mut(capt, vis, ());
                    MutVisitable::visit_mut(body, vis, ());
                    MutVisitable::visit_mut(kind, vis, ());
                    MutVisitable::visit_mut(decl_span, vis, ());
                }
                ExprKind::Await(expr, span) | ExprKind::Use(expr, span) => {
                    MutVisitable::visit_mut(expr, vis, ());
                    MutVisitable::visit_mut(span, vis, ());
                }
                ExprKind::Assign(lhs, rhs, span) => {
                    MutVisitable::visit_mut(lhs, vis, ());
                    MutVisitable::visit_mut(rhs, vis, ());
                    MutVisitable::visit_mut(span, vis, ());
                }
                ExprKind::AssignOp(op, lhs, rhs) => {
                    MutVisitable::visit_mut(op, vis, ());
                    MutVisitable::visit_mut(lhs, vis, ());
                    MutVisitable::visit_mut(rhs, vis, ());
                }
                ExprKind::Field(subexpression, ident) => {
                    MutVisitable::visit_mut(subexpression, vis, ());
                    MutVisitable::visit_mut(ident, vis, ());
                }
                ExprKind::Index(main_expression, index_expression, span) => {
                    MutVisitable::visit_mut(main_expression, vis, ());
                    MutVisitable::visit_mut(index_expression, vis, ());
                    MutVisitable::visit_mut(span, vis, ());
                }
                ExprKind::Range(start, end, limit) => {
                    MutVisitable::visit_mut(start, vis, ());
                    MutVisitable::visit_mut(end, vis, ());
                    MutVisitable::visit_mut(limit, vis, ());
                }
                ExprKind::Underscore => {}
                ExprKind::Path(maybe_qself, path) => {
                    MutVisitable::visit_mut(maybe_qself, vis, ());
                    MutVisitable::visit_mut(path, vis, ());
                }
                ExprKind::Break(opt_label, opt_expr) => {
                    MutVisitable::visit_mut(opt_label, vis, ());
                    MutVisitable::visit_mut(opt_expr, vis, ());
                }
                ExprKind::Continue(opt_label) => {
                    MutVisitable::visit_mut(opt_label, vis, ());
                }
                ExprKind::Ret(optional_expression) |
                    ExprKind::Yeet(optional_expression) => {
                    MutVisitable::visit_mut(optional_expression, vis, ());
                }
                ExprKind::Become(expr) => {
                    MutVisitable::visit_mut(expr, vis, ());
                }
                ExprKind::MacCall(mac) => {
                    MutVisitable::visit_mut(mac, vis, ());
                }
                ExprKind::Paren(subexpression) => {
                    MutVisitable::visit_mut(subexpression, vis, ());
                }
                ExprKind::InlineAsm(asm) => {
                    MutVisitable::visit_mut(asm, vis, ());
                }
                ExprKind::FormatArgs(f) => {
                    MutVisitable::visit_mut(f, vis, ());
                }
                ExprKind::OffsetOf(container, fields) => {
                    MutVisitable::visit_mut(container, vis, ());
                    MutVisitable::visit_mut(fields, vis, ());
                }
                ExprKind::Yield(kind) => {
                    MutVisitable::visit_mut(kind, vis, ());
                }
                ExprKind::Try(subexpression) => {
                    MutVisitable::visit_mut(subexpression, vis, ());
                }
                ExprKind::TryBlock(body, optional_type) => {
                    MutVisitable::visit_mut(body, vis, ());
                    MutVisitable::visit_mut(optional_type, vis, ());
                }
                ExprKind::Lit(token) => {
                    MutVisitable::visit_mut(token, vis, ());
                }
                ExprKind::IncludedBytes(bytes) => {
                    MutVisitable::visit_mut(bytes, vis, ());
                }
                ExprKind::UnsafeBinderCast(kind, expr, ty) => {
                    MutVisitable::visit_mut(kind, vis, ());
                    MutVisitable::visit_mut(expr, vis, ());
                    MutVisitable::visit_mut(ty, vis, ());
                }
                ExprKind::Err(_guar) => {}
                ExprKind::Dummy => {}
            }
            visit_span(vis, span)
        }
    }
}
pub fn walk_anon_const<V: MutVisitor>(visitor: &mut V, node: &mut AnonConst) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_arm<V: MutVisitor>(visitor: &mut V, node: &mut Arm) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_assoc_item_constraint<V: MutVisitor>(visitor: &mut V,
    node: &mut AssocItemConstraint) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_attribute<V: MutVisitor>(visitor: &mut V, node: &mut Attribute) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_block<V: MutVisitor>(visitor: &mut V, node: &mut Block) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_capture_by<V: MutVisitor>(visitor: &mut V, node: &mut CaptureBy) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_closure_binder<V: MutVisitor>(visitor: &mut V,
    node: &mut ClosureBinder) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_contract<V: MutVisitor>(visitor: &mut V, node: &mut FnContract) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_coroutine_kind<V: MutVisitor>(visitor: &mut V,
    node: &mut CoroutineKind) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_crate<V: MutVisitor>(visitor: &mut V, node: &mut Crate) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_expr<V: MutVisitor>(visitor: &mut V, node: &mut Expr) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_expr_field<V: MutVisitor>(visitor: &mut V, node: &mut ExprField) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_field_def<V: MutVisitor>(visitor: &mut V, node: &mut FieldDef) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_fn_decl<V: MutVisitor>(visitor: &mut V, node: &mut FnDecl) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_fn_header<V: MutVisitor>(visitor: &mut V, node: &mut FnHeader) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_fn_ret_ty<V: MutVisitor>(visitor: &mut V, node: &mut FnRetTy) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_foreign_mod<V: MutVisitor>(visitor: &mut V,
    node: &mut ForeignMod) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_format_args<V: MutVisitor>(visitor: &mut V,
    node: &mut FormatArgs) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_generic_arg<V: MutVisitor>(visitor: &mut V,
    node: &mut GenericArg) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_generic_args<V: MutVisitor>(visitor: &mut V,
    node: &mut GenericArgs) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_generic_param<V: MutVisitor>(visitor: &mut V,
    node: &mut GenericParam) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_generics<V: MutVisitor>(visitor: &mut V, node: &mut Generics) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_inline_asm<V: MutVisitor>(visitor: &mut V, node: &mut InlineAsm) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_inline_asm_sym<V: MutVisitor>(visitor: &mut V,
    node: &mut InlineAsmSym) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_label<V: MutVisitor>(visitor: &mut V, node: &mut Label) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_lifetime<V: MutVisitor>(visitor: &mut V, node: &mut Lifetime) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_local<V: MutVisitor>(visitor: &mut V, node: &mut Local) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_mac<V: MutVisitor>(visitor: &mut V, node: &mut MacCall) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_macro_def<V: MutVisitor>(visitor: &mut V, node: &mut MacroDef) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_param_bound<V: MutVisitor>(visitor: &mut V,
    node: &mut GenericBound) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_param<V: MutVisitor>(visitor: &mut V, node: &mut Param) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_pat_field<V: MutVisitor>(visitor: &mut V, node: &mut PatField) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_path<V: MutVisitor>(visitor: &mut V, node: &mut Path) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_path_segment<V: MutVisitor>(visitor: &mut V,
    node: &mut PathSegment) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_pat<V: MutVisitor>(visitor: &mut V, node: &mut Pat) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_poly_trait_ref<V: MutVisitor>(visitor: &mut V,
    node: &mut PolyTraitRef) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_precise_capturing_arg<V: MutVisitor>(visitor: &mut V,
    node: &mut PreciseCapturingArg) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_qself<V: MutVisitor>(visitor: &mut V, node: &mut QSelf) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_trait_ref<V: MutVisitor>(visitor: &mut V, node: &mut TraitRef) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_ty_pat<V: MutVisitor>(visitor: &mut V, node: &mut TyPat) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_ty<V: MutVisitor>(visitor: &mut V, node: &mut Ty) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_use_tree<V: MutVisitor>(visitor: &mut V, node: &mut UseTree) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_variant_data<V: MutVisitor>(visitor: &mut V,
    node: &mut VariantData) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_variant<V: MutVisitor>(visitor: &mut V, node: &mut Variant) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_vis<V: MutVisitor>(visitor: &mut V, node: &mut Visibility) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_where_predicate_kind<V: MutVisitor>(visitor: &mut V,
    node: &mut WherePredicateKind) {
    MutWalkable::walk_mut(node, visitor)
}
pub fn walk_where_predicate<V: MutVisitor>(visitor: &mut V,
    node: &mut WherePredicate) {
    MutWalkable::walk_mut(node, visitor)
}super::common_visitor_and_walkers!((mut) MutVisitor);
263
264macro_rules! generate_flat_map_visitor_fns {
265    ($($name:ident, $Ty:ty, $flat_map_fn:ident$(, $param:ident: $ParamTy:ty)*;)+) => {
266        $(
267            #[allow(unused_parens)]
268            impl<V: MutVisitor> MutVisitable<V> for ThinVec<$Ty> {
269                type Extra = ($($ParamTy),*);
270
271                #[inline]
272                fn visit_mut(
273                    &mut self,
274                    visitor: &mut V,
275                    ($($param),*): Self::Extra,
276                ) -> V::Result {
277                    $name(visitor, self $(, $param)*)
278                }
279            }
280
281            fn $name<V: MutVisitor>(
282                vis: &mut V,
283                values: &mut ThinVec<$Ty>,
284                $(
285                    $param: $ParamTy,
286                )*
287            ) {
288                values.flat_map_in_place(|value| vis.$flat_map_fn(value$(,$param)*));
289            }
290        )+
291    }
292}
293
294#[allow(unused_parens)]
impl<V: MutVisitor> MutVisitable<V> for ThinVec<Arm> {
    type Extra = ();
    #[inline]
    fn visit_mut(&mut self, visitor: &mut V, (): Self::Extra) -> V::Result {
        visit_arms(visitor, self)
    }
}
fn visit_arms<V: MutVisitor>(vis: &mut V, values: &mut ThinVec<Arm>) {
    values.flat_map_in_place(|value| vis.flat_map_arm(value));
}generate_flat_map_visitor_fns! {
295    visit_items, Box<Item>, flat_map_item;
296    visit_foreign_items, Box<ForeignItem>, flat_map_foreign_item;
297    visit_generic_params, GenericParam, flat_map_generic_param;
298    visit_stmts, Stmt, flat_map_stmt;
299    visit_exprs, Box<Expr>, filter_map_expr;
300    visit_expr_fields, ExprField, flat_map_expr_field;
301    visit_pat_fields, PatField, flat_map_pat_field;
302    visit_variants, Variant, flat_map_variant;
303    visit_assoc_items, Box<AssocItem>, flat_map_assoc_item, ctxt: AssocCtxt;
304    visit_where_predicates, WherePredicate, flat_map_where_predicate;
305    visit_params, Param, flat_map_param;
306    visit_field_defs, FieldDef, flat_map_field_def;
307    visit_arms, Arm, flat_map_arm;
308}
309
310pub fn walk_flat_map_pat_field<T: MutVisitor>(
311    vis: &mut T,
312    mut fp: PatField,
313) -> SmallVec<[PatField; 1]> {
314    vis.visit_pat_field(&mut fp);
315    {
    let count = 0usize + 1usize;
    let mut vec = ::smallvec::SmallVec::new();
    if count <= vec.inline_size() {
        vec.push(fp);
        vec
    } else {
        ::smallvec::SmallVec::from_vec(<[_]>::into_vec(::alloc::boxed::box_new([fp])))
    }
}smallvec![fp]
316}
317
318macro_rules! generate_walk_flat_map_fns {
319    ($($fn_name:ident($Ty:ty$(,$extra_name:ident: $ExtraTy:ty)*) => $visit_fn_name:ident;)+) => {$(
320        pub fn $fn_name<V: MutVisitor>(vis: &mut V, mut value: $Ty$(,$extra_name: $ExtraTy)*) -> SmallVec<[$Ty; 1]> {
321            vis.$visit_fn_name(&mut value$(,$extra_name)*);
322            smallvec![value]
323        }
324    )+};
325}
326
327pub fn walk_flat_map_assoc_item<V: MutVisitor>(vis: &mut V,
    mut value: Box<AssocItem>, ctxt: AssocCtxt)
    -> SmallVec<[Box<AssocItem>; 1]> {
    vis.visit_assoc_item(&mut value, ctxt);
    {
        let count = 0usize + 1usize;
        let mut vec = ::smallvec::SmallVec::new();
        if count <= vec.inline_size() {
            vec.push(value);
            vec
        } else {
            ::smallvec::SmallVec::from_vec(<[_]>::into_vec(::alloc::boxed::box_new([value])))
        }
    }
}generate_walk_flat_map_fns! {
328    walk_flat_map_arm(Arm) => visit_arm;
329    walk_flat_map_variant(Variant) => visit_variant;
330    walk_flat_map_param(Param) => visit_param;
331    walk_flat_map_generic_param(GenericParam) => visit_generic_param;
332    walk_flat_map_where_predicate(WherePredicate) => visit_where_predicate;
333    walk_flat_map_field_def(FieldDef) => visit_field_def;
334    walk_flat_map_expr_field(ExprField) => visit_expr_field;
335    walk_flat_map_item(Box<Item>) => visit_item;
336    walk_flat_map_foreign_item(Box<ForeignItem>) => visit_foreign_item;
337    walk_flat_map_assoc_item(Box<AssocItem>, ctxt: AssocCtxt) => visit_assoc_item;
338}
339
340pub fn walk_filter_map_expr<T: MutVisitor>(vis: &mut T, mut e: Box<Expr>) -> Option<Box<Expr>> {
341    vis.visit_expr(&mut e);
342    Some(e)
343}
344
345pub fn walk_flat_map_stmt<T: MutVisitor>(
346    vis: &mut T,
347    Stmt { kind, span, mut id }: Stmt,
348) -> SmallVec<[Stmt; 1]> {
349    vis.visit_id(&mut id);
350    let mut stmts: SmallVec<[Stmt; 1]> = walk_flat_map_stmt_kind(vis, kind)
351        .into_iter()
352        .map(|kind| Stmt { id, kind, span })
353        .collect();
354    match &mut stmts[..] {
355        [] => {}
356        [stmt] => vis.visit_span(&mut stmt.span),
357        _ => {
    ::core::panicking::panic_fmt(format_args!("cloning statement `NodeId`s is prohibited by default, the visitor should implement custom statement visiting"));
}panic!(
358            "cloning statement `NodeId`s is prohibited by default, \
359             the visitor should implement custom statement visiting"
360        ),
361    }
362    stmts
363}
364
365fn walk_flat_map_stmt_kind<T: MutVisitor>(vis: &mut T, kind: StmtKind) -> SmallVec<[StmtKind; 1]> {
366    match kind {
367        StmtKind::Let(mut local) => {
    let count = 0usize + 1usize;
    let mut vec = ::smallvec::SmallVec::new();
    if count <= vec.inline_size() {
        vec.push(StmtKind::Let({ vis.visit_local(&mut local); local }));
        vec
    } else {
        ::smallvec::SmallVec::from_vec(<[_]>::into_vec(::alloc::boxed::box_new([StmtKind::Let({
                                    vis.visit_local(&mut local);
                                    local
                                })])))
    }
}smallvec![StmtKind::Let({
368            vis.visit_local(&mut local);
369            local
370        })],
371        StmtKind::Item(item) => vis.flat_map_item(item).into_iter().map(StmtKind::Item).collect(),
372        StmtKind::Expr(expr) => vis.filter_map_expr(expr).into_iter().map(StmtKind::Expr).collect(),
373        StmtKind::Semi(expr) => vis.filter_map_expr(expr).into_iter().map(StmtKind::Semi).collect(),
374        StmtKind::Empty => {
    let count = 0usize + 1usize;
    let mut vec = ::smallvec::SmallVec::new();
    if count <= vec.inline_size() {
        vec.push(StmtKind::Empty);
        vec
    } else {
        ::smallvec::SmallVec::from_vec(<[_]>::into_vec(::alloc::boxed::box_new([StmtKind::Empty])))
    }
}smallvec![StmtKind::Empty],
375        StmtKind::MacCall(mut mac) => {
376            let MacCallStmt { mac: mac_, style: _, attrs, tokens: _ } = mac.deref_mut();
377            for attr in attrs {
378                vis.visit_attribute(attr);
379            }
380            vis.visit_mac_call(mac_);
381            {
    let count = 0usize + 1usize;
    let mut vec = ::smallvec::SmallVec::new();
    if count <= vec.inline_size() {
        vec.push(StmtKind::MacCall(mac));
        vec
    } else {
        ::smallvec::SmallVec::from_vec(<[_]>::into_vec(::alloc::boxed::box_new([StmtKind::MacCall(mac)])))
    }
}smallvec![StmtKind::MacCall(mac)]
382        }
383    }
384}