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;
12use std::sync::Arc;
13
14use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
15use rustc_data_structures::stack::ensure_sufficient_stack;
16use rustc_span::source_map::Spanned;
17use rustc_span::{Ident, Span};
18use smallvec::{Array, SmallVec, smallvec};
19use thin_vec::ThinVec;
20
21use crate::ast::*;
22use crate::ptr::P;
23use crate::token::{self, Token};
24use crate::tokenstream::*;
25use crate::visit::{AssocCtxt, BoundKind, FnCtxt};
26
27pub trait ExpectOne<A: Array> {
28    fn expect_one(self, err: &'static str) -> A::Item;
29}
30
31impl<A: Array> ExpectOne<A> for SmallVec<A> {
32    fn expect_one(self, err: &'static str) -> A::Item {
33        assert!(self.len() == 1, "{}", err);
34        self.into_iter().next().unwrap()
35    }
36}
37
38pub trait WalkItemKind {
39    type Ctxt;
40    fn walk(
41        &mut self,
42        span: Span,
43        id: NodeId,
44        ident: &mut Ident,
45        visibility: &mut Visibility,
46        ctxt: Self::Ctxt,
47        visitor: &mut impl MutVisitor,
48    );
49}
50
51pub trait MutVisitor: Sized {
52    /// Mutable token visiting only exists for the `macro_rules` token marker and should not be
53    /// used otherwise. Token visitor would be entirely separate from the regular visitor if
54    /// the marker didn't have to visit AST fragments in nonterminal tokens.
55    const VISIT_TOKENS: bool = false;
56
57    // Methods in this trait have one of three forms:
58    //
59    //   fn visit_t(&mut self, t: &mut T);                      // common
60    //   fn flat_map_t(&mut self, t: T) -> SmallVec<[T; 1]>;    // rare
61    //   fn filter_map_t(&mut self, t: T) -> Option<T>;         // rarest
62    //
63    // Any additions to this trait should happen in form of a call to a public
64    // `noop_*` function that only calls out to the visitor again, not other
65    // `noop_*` functions. This is a necessary API workaround to the problem of
66    // not being able to call out to the super default method in an overridden
67    // default method.
68    //
69    // When writing these methods, it is better to use destructuring like this:
70    //
71    //   fn visit_abc(&mut self, ABC { a, b, c: _ }: &mut ABC) {
72    //       visit_a(a);
73    //       visit_b(b);
74    //   }
75    //
76    // than to use field access like this:
77    //
78    //   fn visit_abc(&mut self, abc: &mut ABC) {
79    //       visit_a(&mut abc.a);
80    //       visit_b(&mut abc.b);
81    //       // ignore abc.c
82    //   }
83    //
84    // As well as being more concise, the former is explicit about which fields
85    // are skipped. Furthermore, if a new field is added, the destructuring
86    // version will cause a compile error, which is good. In comparison, the
87    // field access version will continue working and it would be easy to
88    // forget to add handling for it.
89
90    fn visit_crate(&mut self, c: &mut Crate) {
91        walk_crate(self, c)
92    }
93
94    fn visit_meta_list_item(&mut self, list_item: &mut MetaItemInner) {
95        walk_meta_list_item(self, list_item);
96    }
97
98    fn visit_meta_item(&mut self, meta_item: &mut MetaItem) {
99        walk_meta_item(self, meta_item);
100    }
101
102    fn visit_use_tree(&mut self, use_tree: &mut UseTree) {
103        walk_use_tree(self, use_tree);
104    }
105
106    fn visit_foreign_item(&mut self, ni: &mut P<ForeignItem>) {
107        walk_item(self, ni);
108    }
109
110    fn flat_map_foreign_item(&mut self, ni: P<ForeignItem>) -> SmallVec<[P<ForeignItem>; 1]> {
111        walk_flat_map_foreign_item(self, ni)
112    }
113
114    fn visit_item(&mut self, i: &mut P<Item>) {
115        walk_item(self, i);
116    }
117
118    fn flat_map_item(&mut self, i: P<Item>) -> SmallVec<[P<Item>; 1]> {
119        walk_flat_map_item(self, i)
120    }
121
122    fn visit_fn_header(&mut self, header: &mut FnHeader) {
123        walk_fn_header(self, header);
124    }
125
126    fn visit_field_def(&mut self, fd: &mut FieldDef) {
127        walk_field_def(self, fd);
128    }
129
130    fn flat_map_field_def(&mut self, fd: FieldDef) -> SmallVec<[FieldDef; 1]> {
131        walk_flat_map_field_def(self, fd)
132    }
133
134    fn visit_assoc_item(&mut self, i: &mut P<AssocItem>, ctxt: AssocCtxt) {
135        walk_assoc_item(self, i, ctxt)
136    }
137
138    fn flat_map_assoc_item(
139        &mut self,
140        i: P<AssocItem>,
141        ctxt: AssocCtxt,
142    ) -> SmallVec<[P<AssocItem>; 1]> {
143        walk_flat_map_assoc_item(self, i, ctxt)
144    }
145
146    fn visit_contract(&mut self, c: &mut P<FnContract>) {
147        walk_contract(self, c);
148    }
149
150    fn visit_fn_decl(&mut self, d: &mut P<FnDecl>) {
151        walk_fn_decl(self, d);
152    }
153
154    /// `Span` and `NodeId` are mutated at the caller site.
155    fn visit_fn(&mut self, fk: FnKind<'_>, _: Span, _: NodeId) {
156        walk_fn(self, fk)
157    }
158
159    fn visit_coroutine_kind(&mut self, a: &mut CoroutineKind) {
160        walk_coroutine_kind(self, a);
161    }
162
163    fn visit_closure_binder(&mut self, b: &mut ClosureBinder) {
164        walk_closure_binder(self, b);
165    }
166
167    fn visit_block(&mut self, b: &mut P<Block>) {
168        walk_block(self, b);
169    }
170
171    fn flat_map_stmt(&mut self, s: Stmt) -> SmallVec<[Stmt; 1]> {
172        walk_flat_map_stmt(self, s)
173    }
174
175    fn visit_arm(&mut self, arm: &mut Arm) {
176        walk_arm(self, arm);
177    }
178
179    fn flat_map_arm(&mut self, arm: Arm) -> SmallVec<[Arm; 1]> {
180        walk_flat_map_arm(self, arm)
181    }
182
183    fn visit_pat(&mut self, p: &mut P<Pat>) {
184        walk_pat(self, p);
185    }
186
187    fn visit_anon_const(&mut self, c: &mut AnonConst) {
188        walk_anon_const(self, c);
189    }
190
191    fn visit_expr(&mut self, e: &mut P<Expr>) {
192        walk_expr(self, e);
193    }
194
195    /// This method is a hack to workaround unstable of `stmt_expr_attributes`.
196    /// It can be removed once that feature is stabilized.
197    fn visit_method_receiver_expr(&mut self, ex: &mut P<Expr>) {
198        self.visit_expr(ex)
199    }
200
201    fn filter_map_expr(&mut self, e: P<Expr>) -> Option<P<Expr>> {
202        noop_filter_map_expr(self, e)
203    }
204
205    fn visit_generic_arg(&mut self, arg: &mut GenericArg) {
206        walk_generic_arg(self, arg);
207    }
208
209    fn visit_ty(&mut self, t: &mut P<Ty>) {
210        walk_ty(self, t);
211    }
212
213    fn visit_ty_pat(&mut self, t: &mut P<TyPat>) {
214        walk_ty_pat(self, t);
215    }
216
217    fn visit_lifetime(&mut self, l: &mut Lifetime) {
218        walk_lifetime(self, l);
219    }
220
221    fn visit_assoc_item_constraint(&mut self, c: &mut AssocItemConstraint) {
222        walk_assoc_item_constraint(self, c);
223    }
224
225    fn visit_foreign_mod(&mut self, nm: &mut ForeignMod) {
226        walk_foreign_mod(self, nm);
227    }
228
229    fn visit_variant(&mut self, v: &mut Variant) {
230        walk_variant(self, v);
231    }
232
233    fn flat_map_variant(&mut self, v: Variant) -> SmallVec<[Variant; 1]> {
234        walk_flat_map_variant(self, v)
235    }
236
237    fn visit_ident(&mut self, i: &mut Ident) {
238        walk_ident(self, i);
239    }
240
241    fn visit_modifiers(&mut self, m: &mut TraitBoundModifiers) {
242        walk_modifiers(self, m);
243    }
244
245    fn visit_path(&mut self, p: &mut Path) {
246        walk_path(self, p);
247    }
248
249    fn visit_path_segment(&mut self, p: &mut PathSegment) {
250        walk_path_segment(self, p)
251    }
252
253    fn visit_qself(&mut self, qs: &mut Option<P<QSelf>>) {
254        walk_qself(self, qs);
255    }
256
257    fn visit_generic_args(&mut self, p: &mut GenericArgs) {
258        walk_generic_args(self, p);
259    }
260
261    fn visit_angle_bracketed_parameter_data(&mut self, p: &mut AngleBracketedArgs) {
262        walk_angle_bracketed_parameter_data(self, p);
263    }
264
265    fn visit_parenthesized_parameter_data(&mut self, p: &mut ParenthesizedArgs) {
266        walk_parenthesized_parameter_data(self, p);
267    }
268
269    fn visit_local(&mut self, l: &mut P<Local>) {
270        walk_local(self, l);
271    }
272
273    fn visit_mac_call(&mut self, mac: &mut MacCall) {
274        walk_mac(self, mac);
275    }
276
277    fn visit_macro_def(&mut self, def: &mut MacroDef) {
278        walk_macro_def(self, def);
279    }
280
281    fn visit_label(&mut self, label: &mut Label) {
282        walk_label(self, label);
283    }
284
285    fn visit_attribute(&mut self, at: &mut Attribute) {
286        walk_attribute(self, at);
287    }
288
289    fn visit_param(&mut self, param: &mut Param) {
290        walk_param(self, param);
291    }
292
293    fn flat_map_param(&mut self, param: Param) -> SmallVec<[Param; 1]> {
294        walk_flat_map_param(self, param)
295    }
296
297    fn visit_generics(&mut self, generics: &mut Generics) {
298        walk_generics(self, generics);
299    }
300
301    fn visit_trait_ref(&mut self, tr: &mut TraitRef) {
302        walk_trait_ref(self, tr);
303    }
304
305    fn visit_poly_trait_ref(&mut self, p: &mut PolyTraitRef) {
306        walk_poly_trait_ref(self, p);
307    }
308
309    fn visit_variant_data(&mut self, vdata: &mut VariantData) {
310        walk_variant_data(self, vdata);
311    }
312
313    fn visit_generic_param(&mut self, param: &mut GenericParam) {
314        walk_generic_param(self, param)
315    }
316
317    fn flat_map_generic_param(&mut self, param: GenericParam) -> SmallVec<[GenericParam; 1]> {
318        walk_flat_map_generic_param(self, param)
319    }
320
321    fn visit_param_bound(&mut self, tpb: &mut GenericBound, _ctxt: BoundKind) {
322        walk_param_bound(self, tpb);
323    }
324
325    fn visit_precise_capturing_arg(&mut self, arg: &mut PreciseCapturingArg) {
326        walk_precise_capturing_arg(self, arg);
327    }
328
329    fn visit_mt(&mut self, mt: &mut MutTy) {
330        walk_mt(self, mt);
331    }
332
333    fn visit_expr_field(&mut self, f: &mut ExprField) {
334        walk_expr_field(self, f);
335    }
336
337    fn flat_map_expr_field(&mut self, f: ExprField) -> SmallVec<[ExprField; 1]> {
338        walk_flat_map_expr_field(self, f)
339    }
340
341    fn visit_where_clause(&mut self, where_clause: &mut WhereClause) {
342        walk_where_clause(self, where_clause);
343    }
344
345    fn flat_map_where_predicate(
346        &mut self,
347        where_predicate: WherePredicate,
348    ) -> SmallVec<[WherePredicate; 1]> {
349        walk_flat_map_where_predicate(self, where_predicate)
350    }
351
352    fn visit_where_predicate_kind(&mut self, kind: &mut WherePredicateKind) {
353        walk_where_predicate_kind(self, kind)
354    }
355
356    fn visit_vis(&mut self, vis: &mut Visibility) {
357        walk_vis(self, vis);
358    }
359
360    fn visit_id(&mut self, _id: &mut NodeId) {
361        // Do nothing.
362    }
363
364    fn visit_span(&mut self, _sp: &mut Span) {
365        // Do nothing.
366    }
367
368    fn visit_pat_field(&mut self, fp: &mut PatField) {
369        walk_pat_field(self, fp)
370    }
371
372    fn flat_map_pat_field(&mut self, fp: PatField) -> SmallVec<[PatField; 1]> {
373        walk_flat_map_pat_field(self, fp)
374    }
375
376    fn visit_inline_asm(&mut self, asm: &mut InlineAsm) {
377        walk_inline_asm(self, asm)
378    }
379
380    fn visit_inline_asm_sym(&mut self, sym: &mut InlineAsmSym) {
381        walk_inline_asm_sym(self, sym)
382    }
383
384    fn visit_format_args(&mut self, fmt: &mut FormatArgs) {
385        walk_format_args(self, fmt)
386    }
387
388    fn visit_capture_by(&mut self, capture_by: &mut CaptureBy) {
389        walk_capture_by(self, capture_by)
390    }
391
392    fn visit_fn_ret_ty(&mut self, fn_ret_ty: &mut FnRetTy) {
393        walk_fn_ret_ty(self, fn_ret_ty)
394    }
395}
396
397/// Use a map-style function (`FnOnce(T) -> T`) to overwrite a `&mut T`. Useful
398/// when using a `flat_map_*` or `filter_map_*` method within a `visit_`
399/// method.
400//
401// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
402pub fn visit_clobber<T: DummyAstNode>(t: &mut T, f: impl FnOnce(T) -> T) {
403    let old_t = std::mem::replace(t, T::dummy());
404    *t = f(old_t);
405}
406
407// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
408#[inline]
409fn visit_vec<T, F>(elems: &mut Vec<T>, mut visit_elem: F)
410where
411    F: FnMut(&mut T),
412{
413    for elem in elems {
414        visit_elem(elem);
415    }
416}
417
418// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
419#[inline]
420fn visit_thin_vec<T, F>(elems: &mut ThinVec<T>, mut visit_elem: F)
421where
422    F: FnMut(&mut T),
423{
424    for elem in elems {
425        visit_elem(elem);
426    }
427}
428
429// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
430#[inline]
431fn visit_opt<T, F>(opt: &mut Option<T>, mut visit_elem: F)
432where
433    F: FnMut(&mut T),
434{
435    if let Some(elem) = opt {
436        visit_elem(elem);
437    }
438}
439
440// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
441fn visit_attrs<T: MutVisitor>(vis: &mut T, attrs: &mut AttrVec) {
442    for attr in attrs.iter_mut() {
443        vis.visit_attribute(attr);
444    }
445}
446
447// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
448#[allow(unused)]
449fn visit_exprs<T: MutVisitor>(vis: &mut T, exprs: &mut Vec<P<Expr>>) {
450    exprs.flat_map_in_place(|expr| vis.filter_map_expr(expr))
451}
452
453// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
454fn visit_thin_exprs<T: MutVisitor>(vis: &mut T, exprs: &mut ThinVec<P<Expr>>) {
455    exprs.flat_map_in_place(|expr| vis.filter_map_expr(expr))
456}
457
458// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
459fn visit_bounds<T: MutVisitor>(vis: &mut T, bounds: &mut GenericBounds, ctxt: BoundKind) {
460    visit_vec(bounds, |bound| vis.visit_param_bound(bound, ctxt));
461}
462
463// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
464fn visit_attr_args<T: MutVisitor>(vis: &mut T, args: &mut AttrArgs) {
465    match args {
466        AttrArgs::Empty => {}
467        AttrArgs::Delimited(args) => visit_delim_args(vis, args),
468        AttrArgs::Eq { eq_span, expr } => {
469            vis.visit_expr(expr);
470            vis.visit_span(eq_span);
471        }
472    }
473}
474
475// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
476fn visit_delim_args<T: MutVisitor>(vis: &mut T, args: &mut DelimArgs) {
477    let DelimArgs { dspan, delim: _, tokens } = args;
478    visit_tts(vis, tokens);
479    visit_delim_span(vis, dspan);
480}
481
482pub fn visit_delim_span<T: MutVisitor>(vis: &mut T, DelimSpan { open, close }: &mut DelimSpan) {
483    vis.visit_span(open);
484    vis.visit_span(close);
485}
486
487pub fn walk_pat_field<T: MutVisitor>(vis: &mut T, fp: &mut PatField) {
488    let PatField { attrs, id, ident, is_placeholder: _, is_shorthand: _, pat, span } = fp;
489    vis.visit_id(id);
490    visit_attrs(vis, attrs);
491    vis.visit_ident(ident);
492    vis.visit_pat(pat);
493    vis.visit_span(span);
494}
495
496pub fn walk_flat_map_pat_field<T: MutVisitor>(
497    vis: &mut T,
498    mut fp: PatField,
499) -> SmallVec<[PatField; 1]> {
500    vis.visit_pat_field(&mut fp);
501    smallvec![fp]
502}
503
504fn walk_use_tree<T: MutVisitor>(vis: &mut T, use_tree: &mut UseTree) {
505    let UseTree { prefix, kind, span } = use_tree;
506    vis.visit_path(prefix);
507    match kind {
508        UseTreeKind::Simple(rename) => visit_opt(rename, |rename| vis.visit_ident(rename)),
509        UseTreeKind::Nested { items, span } => {
510            for (tree, id) in items {
511                vis.visit_id(id);
512                vis.visit_use_tree(tree);
513            }
514            vis.visit_span(span);
515        }
516        UseTreeKind::Glob => {}
517    }
518    vis.visit_span(span);
519}
520
521pub fn walk_arm<T: MutVisitor>(vis: &mut T, arm: &mut Arm) {
522    let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = arm;
523    vis.visit_id(id);
524    visit_attrs(vis, attrs);
525    vis.visit_pat(pat);
526    visit_opt(guard, |guard| vis.visit_expr(guard));
527    visit_opt(body, |body| vis.visit_expr(body));
528    vis.visit_span(span);
529}
530
531pub fn walk_flat_map_arm<T: MutVisitor>(vis: &mut T, mut arm: Arm) -> SmallVec<[Arm; 1]> {
532    vis.visit_arm(&mut arm);
533    smallvec![arm]
534}
535
536fn walk_assoc_item_constraint<T: MutVisitor>(
537    vis: &mut T,
538    AssocItemConstraint { id, ident, gen_args, kind, span }: &mut AssocItemConstraint,
539) {
540    vis.visit_id(id);
541    vis.visit_ident(ident);
542    if let Some(gen_args) = gen_args {
543        vis.visit_generic_args(gen_args);
544    }
545    match kind {
546        AssocItemConstraintKind::Equality { term } => match term {
547            Term::Ty(ty) => vis.visit_ty(ty),
548            Term::Const(c) => vis.visit_anon_const(c),
549        },
550        AssocItemConstraintKind::Bound { bounds } => visit_bounds(vis, bounds, BoundKind::Bound),
551    }
552    vis.visit_span(span);
553}
554
555pub fn walk_ty<T: MutVisitor>(vis: &mut T, ty: &mut P<Ty>) {
556    let Ty { id, kind, span, tokens } = ty.deref_mut();
557    vis.visit_id(id);
558    match kind {
559        TyKind::Err(_guar) => {}
560        TyKind::Infer | TyKind::ImplicitSelf | TyKind::Dummy | TyKind::Never | TyKind::CVarArgs => {
561        }
562        TyKind::Slice(ty) => vis.visit_ty(ty),
563        TyKind::Ptr(mt) => vis.visit_mt(mt),
564        TyKind::Ref(lt, mt) | TyKind::PinnedRef(lt, mt) => {
565            visit_opt(lt, |lt| vis.visit_lifetime(lt));
566            vis.visit_mt(mt);
567        }
568        TyKind::BareFn(bft) => {
569            let BareFnTy { safety, ext: _, generic_params, decl, decl_span } = bft.deref_mut();
570            visit_safety(vis, safety);
571            generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
572            vis.visit_fn_decl(decl);
573            vis.visit_span(decl_span);
574        }
575        TyKind::UnsafeBinder(binder) => {
576            let UnsafeBinderTy { generic_params, inner_ty } = binder.deref_mut();
577            generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
578            vis.visit_ty(inner_ty);
579        }
580        TyKind::Tup(tys) => visit_thin_vec(tys, |ty| vis.visit_ty(ty)),
581        TyKind::Paren(ty) => vis.visit_ty(ty),
582        TyKind::Pat(ty, pat) => {
583            vis.visit_ty(ty);
584            vis.visit_ty_pat(pat);
585        }
586        TyKind::Path(qself, path) => {
587            vis.visit_qself(qself);
588            vis.visit_path(path);
589        }
590        TyKind::Array(ty, length) => {
591            vis.visit_ty(ty);
592            vis.visit_anon_const(length);
593        }
594        TyKind::Typeof(expr) => vis.visit_anon_const(expr),
595        TyKind::TraitObject(bounds, _syntax) => {
596            visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::TraitObject))
597        }
598        TyKind::ImplTrait(id, bounds) => {
599            vis.visit_id(id);
600            visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Impl));
601        }
602        TyKind::MacCall(mac) => vis.visit_mac_call(mac),
603    }
604    visit_lazy_tts(vis, tokens);
605    vis.visit_span(span);
606}
607
608pub fn walk_ty_pat<T: MutVisitor>(vis: &mut T, ty: &mut P<TyPat>) {
609    let TyPat { id, kind, span, tokens } = ty.deref_mut();
610    vis.visit_id(id);
611    match kind {
612        TyPatKind::Range(start, end, _include_end) => {
613            visit_opt(start, |c| vis.visit_anon_const(c));
614            visit_opt(end, |c| vis.visit_anon_const(c));
615        }
616        TyPatKind::Err(_) => {}
617    }
618    visit_lazy_tts(vis, tokens);
619    vis.visit_span(span);
620}
621
622fn walk_foreign_mod<T: MutVisitor>(vis: &mut T, foreign_mod: &mut ForeignMod) {
623    let ForeignMod { extern_span: _, safety, abi: _, items } = foreign_mod;
624    visit_safety(vis, safety);
625    items.flat_map_in_place(|item| vis.flat_map_foreign_item(item));
626}
627
628pub fn walk_variant<T: MutVisitor>(visitor: &mut T, variant: &mut Variant) {
629    let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = variant;
630    visitor.visit_id(id);
631    visit_attrs(visitor, attrs);
632    visitor.visit_vis(vis);
633    visitor.visit_ident(ident);
634    visitor.visit_variant_data(data);
635    visit_opt(disr_expr, |disr_expr| visitor.visit_anon_const(disr_expr));
636    visitor.visit_span(span);
637}
638
639pub fn walk_flat_map_variant<T: MutVisitor>(
640    vis: &mut T,
641    mut variant: Variant,
642) -> SmallVec<[Variant; 1]> {
643    vis.visit_variant(&mut variant);
644    smallvec![variant]
645}
646
647fn walk_ident<T: MutVisitor>(vis: &mut T, Ident { name: _, span }: &mut Ident) {
648    vis.visit_span(span);
649}
650
651fn walk_path_segment<T: MutVisitor>(vis: &mut T, segment: &mut PathSegment) {
652    let PathSegment { ident, id, args } = segment;
653    vis.visit_id(id);
654    vis.visit_ident(ident);
655    visit_opt(args, |args| vis.visit_generic_args(args));
656}
657
658fn walk_path<T: MutVisitor>(vis: &mut T, Path { segments, span, tokens }: &mut Path) {
659    for segment in segments {
660        vis.visit_path_segment(segment);
661    }
662    visit_lazy_tts(vis, tokens);
663    vis.visit_span(span);
664}
665
666fn walk_qself<T: MutVisitor>(vis: &mut T, qself: &mut Option<P<QSelf>>) {
667    visit_opt(qself, |qself| {
668        let QSelf { ty, path_span, position: _ } = &mut **qself;
669        vis.visit_ty(ty);
670        vis.visit_span(path_span);
671    })
672}
673
674fn walk_generic_args<T: MutVisitor>(vis: &mut T, generic_args: &mut GenericArgs) {
675    match generic_args {
676        GenericArgs::AngleBracketed(data) => vis.visit_angle_bracketed_parameter_data(data),
677        GenericArgs::Parenthesized(data) => vis.visit_parenthesized_parameter_data(data),
678        GenericArgs::ParenthesizedElided(span) => vis.visit_span(span),
679    }
680}
681
682fn walk_generic_arg<T: MutVisitor>(vis: &mut T, arg: &mut GenericArg) {
683    match arg {
684        GenericArg::Lifetime(lt) => vis.visit_lifetime(lt),
685        GenericArg::Type(ty) => vis.visit_ty(ty),
686        GenericArg::Const(ct) => vis.visit_anon_const(ct),
687    }
688}
689
690fn walk_angle_bracketed_parameter_data<T: MutVisitor>(vis: &mut T, data: &mut AngleBracketedArgs) {
691    let AngleBracketedArgs { args, span } = data;
692    visit_thin_vec(args, |arg| match arg {
693        AngleBracketedArg::Arg(arg) => vis.visit_generic_arg(arg),
694        AngleBracketedArg::Constraint(constraint) => vis.visit_assoc_item_constraint(constraint),
695    });
696    vis.visit_span(span);
697}
698
699fn walk_parenthesized_parameter_data<T: MutVisitor>(vis: &mut T, args: &mut ParenthesizedArgs) {
700    let ParenthesizedArgs { inputs, output, span, inputs_span } = args;
701    visit_thin_vec(inputs, |input| vis.visit_ty(input));
702    vis.visit_fn_ret_ty(output);
703    vis.visit_span(span);
704    vis.visit_span(inputs_span);
705}
706
707fn walk_local<T: MutVisitor>(vis: &mut T, local: &mut P<Local>) {
708    let Local { id, pat, ty, kind, span, colon_sp, attrs, tokens } = local.deref_mut();
709    vis.visit_id(id);
710    visit_attrs(vis, attrs);
711    vis.visit_pat(pat);
712    visit_opt(ty, |ty| vis.visit_ty(ty));
713    match kind {
714        LocalKind::Decl => {}
715        LocalKind::Init(init) => {
716            vis.visit_expr(init);
717        }
718        LocalKind::InitElse(init, els) => {
719            vis.visit_expr(init);
720            vis.visit_block(els);
721        }
722    }
723    visit_lazy_tts(vis, tokens);
724    visit_opt(colon_sp, |sp| vis.visit_span(sp));
725    vis.visit_span(span);
726}
727
728fn walk_attribute<T: MutVisitor>(vis: &mut T, attr: &mut Attribute) {
729    let Attribute { kind, id: _, style: _, span } = attr;
730    match kind {
731        AttrKind::Normal(normal) => {
732            let NormalAttr {
733                item: AttrItem { unsafety: _, path, args, tokens },
734                tokens: attr_tokens,
735            } = &mut **normal;
736            vis.visit_path(path);
737            visit_attr_args(vis, args);
738            visit_lazy_tts(vis, tokens);
739            visit_lazy_tts(vis, attr_tokens);
740        }
741        AttrKind::DocComment(_kind, _sym) => {}
742    }
743    vis.visit_span(span);
744}
745
746fn walk_mac<T: MutVisitor>(vis: &mut T, mac: &mut MacCall) {
747    let MacCall { path, args } = mac;
748    vis.visit_path(path);
749    visit_delim_args(vis, args);
750}
751
752fn walk_macro_def<T: MutVisitor>(vis: &mut T, macro_def: &mut MacroDef) {
753    let MacroDef { body, macro_rules: _ } = macro_def;
754    visit_delim_args(vis, body);
755}
756
757fn walk_meta_list_item<T: MutVisitor>(vis: &mut T, li: &mut MetaItemInner) {
758    match li {
759        MetaItemInner::MetaItem(mi) => vis.visit_meta_item(mi),
760        MetaItemInner::Lit(_lit) => {}
761    }
762}
763
764fn walk_meta_item<T: MutVisitor>(vis: &mut T, mi: &mut MetaItem) {
765    let MetaItem { unsafety: _, path: _, kind, span } = mi;
766    match kind {
767        MetaItemKind::Word => {}
768        MetaItemKind::List(mis) => visit_thin_vec(mis, |mi| vis.visit_meta_list_item(mi)),
769        MetaItemKind::NameValue(_s) => {}
770    }
771    vis.visit_span(span);
772}
773
774pub fn walk_param<T: MutVisitor>(vis: &mut T, param: &mut Param) {
775    let Param { attrs, id, pat, span, ty, is_placeholder: _ } = param;
776    vis.visit_id(id);
777    visit_attrs(vis, attrs);
778    vis.visit_pat(pat);
779    vis.visit_ty(ty);
780    vis.visit_span(span);
781}
782
783pub fn walk_flat_map_param<T: MutVisitor>(vis: &mut T, mut param: Param) -> SmallVec<[Param; 1]> {
784    vis.visit_param(&mut param);
785    smallvec![param]
786}
787
788// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
789fn visit_attr_tt<T: MutVisitor>(vis: &mut T, tt: &mut AttrTokenTree) {
790    match tt {
791        AttrTokenTree::Token(token, _spacing) => {
792            visit_token(vis, token);
793        }
794        AttrTokenTree::Delimited(dspan, _spacing, _delim, tts) => {
795            visit_attr_tts(vis, tts);
796            visit_delim_span(vis, dspan);
797        }
798        AttrTokenTree::AttrsTarget(AttrsTarget { attrs, tokens }) => {
799            visit_attrs(vis, attrs);
800            visit_lazy_tts_opt_mut(vis, Some(tokens));
801        }
802    }
803}
804
805// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
806fn visit_tt<T: MutVisitor>(vis: &mut T, tt: &mut TokenTree) {
807    match tt {
808        TokenTree::Token(token, _spacing) => {
809            visit_token(vis, token);
810        }
811        TokenTree::Delimited(dspan, _spacing, _delim, tts) => {
812            visit_tts(vis, tts);
813            visit_delim_span(vis, dspan);
814        }
815    }
816}
817
818// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
819fn visit_tts<T: MutVisitor>(vis: &mut T, TokenStream(tts): &mut TokenStream) {
820    if T::VISIT_TOKENS && !tts.is_empty() {
821        let tts = Arc::make_mut(tts);
822        visit_vec(tts, |tree| visit_tt(vis, tree));
823    }
824}
825
826fn visit_attr_tts<T: MutVisitor>(vis: &mut T, AttrTokenStream(tts): &mut AttrTokenStream) {
827    if T::VISIT_TOKENS && !tts.is_empty() {
828        let tts = Arc::make_mut(tts);
829        visit_vec(tts, |tree| visit_attr_tt(vis, tree));
830    }
831}
832
833fn visit_lazy_tts_opt_mut<T: MutVisitor>(vis: &mut T, lazy_tts: Option<&mut LazyAttrTokenStream>) {
834    if T::VISIT_TOKENS {
835        if let Some(lazy_tts) = lazy_tts {
836            let mut tts = lazy_tts.to_attr_token_stream();
837            visit_attr_tts(vis, &mut tts);
838            *lazy_tts = LazyAttrTokenStream::new(tts);
839        }
840    }
841}
842
843fn visit_lazy_tts<T: MutVisitor>(vis: &mut T, lazy_tts: &mut Option<LazyAttrTokenStream>) {
844    visit_lazy_tts_opt_mut(vis, lazy_tts.as_mut());
845}
846
847/// Applies ident visitor if it's an ident; applies other visits to interpolated nodes.
848/// In practice the ident part is not actually used by specific visitors right now,
849/// but there's a test below checking that it works.
850// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
851pub fn visit_token<T: MutVisitor>(vis: &mut T, t: &mut Token) {
852    let Token { kind, span } = t;
853    match kind {
854        token::Ident(name, _is_raw) | token::Lifetime(name, _is_raw) => {
855            let mut ident = Ident::new(*name, *span);
856            vis.visit_ident(&mut ident);
857            *name = ident.name;
858            *span = ident.span;
859            return; // Avoid visiting the span for the second time.
860        }
861        token::NtIdent(ident, _is_raw) => {
862            vis.visit_ident(ident);
863        }
864        token::NtLifetime(ident, _is_raw) => {
865            vis.visit_ident(ident);
866        }
867        token::Interpolated(nt) => {
868            let nt = Arc::make_mut(nt);
869            visit_nonterminal(vis, nt);
870        }
871        _ => {}
872    }
873    vis.visit_span(span);
874}
875
876// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
877/// Applies the visitor to elements of interpolated nodes.
878//
879// N.B., this can occur only when applying a visitor to partially expanded
880// code, where parsed pieces have gotten implanted ito *other* macro
881// invocations. This is relevant for macro hygiene, but possibly not elsewhere.
882//
883// One problem here occurs because the types for flat_map_item, flat_map_stmt,
884// etc., allow the visitor to return *multiple* items; this is a problem for the
885// nodes here, because they insist on having exactly one piece. One solution
886// would be to mangle the MutVisitor trait to include one-to-many and
887// one-to-one versions of these entry points, but that would probably confuse a
888// lot of people and help very few. Instead, I'm just going to put in dynamic
889// checks. I think the performance impact of this will be pretty much
890// nonexistent. The danger is that someone will apply a `MutVisitor` to a
891// partially expanded node, and will be confused by the fact that their
892// `flat_map_item` or `flat_map_stmt` isn't getting called on `NtItem` or `NtStmt`
893// nodes. Hopefully they'll wind up reading this comment, and doing something
894// appropriate.
895//
896// BTW, design choice: I considered just changing the type of, e.g., `NtItem` to
897// contain multiple items, but decided against it when I looked at
898// `parse_item_or_view_item` and tried to figure out what I would do with
899// multiple items there....
900fn visit_nonterminal<T: MutVisitor>(vis: &mut T, nt: &mut token::Nonterminal) {
901    match nt {
902        token::NtBlock(block) => vis.visit_block(block),
903        token::NtExpr(expr) => vis.visit_expr(expr),
904        token::NtLiteral(expr) => vis.visit_expr(expr),
905    }
906}
907
908// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
909fn visit_defaultness<T: MutVisitor>(vis: &mut T, defaultness: &mut Defaultness) {
910    match defaultness {
911        Defaultness::Default(span) => vis.visit_span(span),
912        Defaultness::Final => {}
913    }
914}
915
916// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
917fn visit_safety<T: MutVisitor>(vis: &mut T, safety: &mut Safety) {
918    match safety {
919        Safety::Unsafe(span) => vis.visit_span(span),
920        Safety::Safe(span) => vis.visit_span(span),
921        Safety::Default => {}
922    }
923}
924
925// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
926fn visit_polarity<T: MutVisitor>(vis: &mut T, polarity: &mut ImplPolarity) {
927    match polarity {
928        ImplPolarity::Positive => {}
929        ImplPolarity::Negative(span) => vis.visit_span(span),
930    }
931}
932
933// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
934fn visit_constness<T: MutVisitor>(vis: &mut T, constness: &mut Const) {
935    match constness {
936        Const::Yes(span) => vis.visit_span(span),
937        Const::No => {}
938    }
939}
940
941fn walk_closure_binder<T: MutVisitor>(vis: &mut T, binder: &mut ClosureBinder) {
942    match binder {
943        ClosureBinder::NotPresent => {}
944        ClosureBinder::For { span: _, generic_params } => {
945            generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
946        }
947    }
948}
949
950fn walk_coroutine_kind<T: MutVisitor>(vis: &mut T, coroutine_kind: &mut CoroutineKind) {
951    match coroutine_kind {
952        CoroutineKind::Async { span, closure_id, return_impl_trait_id }
953        | CoroutineKind::Gen { span, closure_id, return_impl_trait_id }
954        | CoroutineKind::AsyncGen { span, closure_id, return_impl_trait_id } => {
955            vis.visit_id(closure_id);
956            vis.visit_id(return_impl_trait_id);
957            vis.visit_span(span);
958        }
959    }
960}
961
962fn walk_fn<T: MutVisitor>(vis: &mut T, kind: FnKind<'_>) {
963    match kind {
964        FnKind::Fn(
965            _ctxt,
966            _ident,
967            _vis,
968            Fn {
969                defaultness,
970                generics,
971                contract,
972                body,
973                sig: FnSig { header, decl, span },
974                define_opaque,
975            },
976        ) => {
977            // Identifier and visibility are visited as a part of the item.
978            visit_defaultness(vis, defaultness);
979            vis.visit_fn_header(header);
980            vis.visit_generics(generics);
981            vis.visit_fn_decl(decl);
982            if let Some(contract) = contract {
983                vis.visit_contract(contract);
984            }
985            if let Some(body) = body {
986                vis.visit_block(body);
987            }
988            vis.visit_span(span);
989
990            walk_define_opaques(vis, define_opaque);
991        }
992        FnKind::Closure(binder, coroutine_kind, decl, body) => {
993            vis.visit_closure_binder(binder);
994            coroutine_kind.as_mut().map(|coroutine_kind| vis.visit_coroutine_kind(coroutine_kind));
995            vis.visit_fn_decl(decl);
996            vis.visit_expr(body);
997        }
998    }
999}
1000
1001fn walk_contract<T: MutVisitor>(vis: &mut T, contract: &mut P<FnContract>) {
1002    let FnContract { requires, ensures } = contract.deref_mut();
1003    if let Some(pred) = requires {
1004        vis.visit_expr(pred);
1005    }
1006    if let Some(pred) = ensures {
1007        vis.visit_expr(pred);
1008    }
1009}
1010
1011fn walk_fn_decl<T: MutVisitor>(vis: &mut T, decl: &mut P<FnDecl>) {
1012    let FnDecl { inputs, output } = decl.deref_mut();
1013    inputs.flat_map_in_place(|param| vis.flat_map_param(param));
1014    vis.visit_fn_ret_ty(output);
1015}
1016
1017fn walk_fn_ret_ty<T: MutVisitor>(vis: &mut T, fn_ret_ty: &mut FnRetTy) {
1018    match fn_ret_ty {
1019        FnRetTy::Default(span) => vis.visit_span(span),
1020        FnRetTy::Ty(ty) => vis.visit_ty(ty),
1021    }
1022}
1023
1024fn walk_param_bound<T: MutVisitor>(vis: &mut T, pb: &mut GenericBound) {
1025    match pb {
1026        GenericBound::Trait(trait_ref) => vis.visit_poly_trait_ref(trait_ref),
1027        GenericBound::Outlives(lifetime) => walk_lifetime(vis, lifetime),
1028        GenericBound::Use(args, span) => {
1029            for arg in args {
1030                vis.visit_precise_capturing_arg(arg);
1031            }
1032            vis.visit_span(span);
1033        }
1034    }
1035}
1036
1037fn walk_precise_capturing_arg<T: MutVisitor>(vis: &mut T, arg: &mut PreciseCapturingArg) {
1038    match arg {
1039        PreciseCapturingArg::Lifetime(lt) => {
1040            vis.visit_lifetime(lt);
1041        }
1042        PreciseCapturingArg::Arg(path, id) => {
1043            vis.visit_id(id);
1044            vis.visit_path(path);
1045        }
1046    }
1047}
1048
1049pub fn walk_generic_param<T: MutVisitor>(vis: &mut T, param: &mut GenericParam) {
1050    let GenericParam { id, ident, attrs, bounds, kind, colon_span, is_placeholder: _ } = param;
1051    vis.visit_id(id);
1052    visit_attrs(vis, attrs);
1053    vis.visit_ident(ident);
1054    visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound));
1055    match kind {
1056        GenericParamKind::Lifetime => {}
1057        GenericParamKind::Type { default } => {
1058            visit_opt(default, |default| vis.visit_ty(default));
1059        }
1060        GenericParamKind::Const { ty, kw_span: _, default } => {
1061            vis.visit_ty(ty);
1062            visit_opt(default, |default| vis.visit_anon_const(default));
1063        }
1064    }
1065    if let Some(colon_span) = colon_span {
1066        vis.visit_span(colon_span);
1067    }
1068}
1069
1070pub fn walk_flat_map_generic_param<T: MutVisitor>(
1071    vis: &mut T,
1072    mut param: GenericParam,
1073) -> SmallVec<[GenericParam; 1]> {
1074    vis.visit_generic_param(&mut param);
1075    smallvec![param]
1076}
1077
1078fn walk_label<T: MutVisitor>(vis: &mut T, Label { ident }: &mut Label) {
1079    vis.visit_ident(ident);
1080}
1081
1082fn walk_lifetime<T: MutVisitor>(vis: &mut T, Lifetime { id, ident }: &mut Lifetime) {
1083    vis.visit_id(id);
1084    vis.visit_ident(ident);
1085}
1086
1087fn walk_generics<T: MutVisitor>(vis: &mut T, generics: &mut Generics) {
1088    let Generics { params, where_clause, span } = generics;
1089    params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
1090    vis.visit_where_clause(where_clause);
1091    vis.visit_span(span);
1092}
1093
1094fn walk_ty_alias_where_clauses<T: MutVisitor>(vis: &mut T, tawcs: &mut TyAliasWhereClauses) {
1095    let TyAliasWhereClauses { before, after, split: _ } = tawcs;
1096    let TyAliasWhereClause { has_where_token: _, span: span_before } = before;
1097    let TyAliasWhereClause { has_where_token: _, span: span_after } = after;
1098    vis.visit_span(span_before);
1099    vis.visit_span(span_after);
1100}
1101
1102fn walk_where_clause<T: MutVisitor>(vis: &mut T, wc: &mut WhereClause) {
1103    let WhereClause { has_where_token: _, predicates, span } = wc;
1104    predicates.flat_map_in_place(|predicate| vis.flat_map_where_predicate(predicate));
1105    vis.visit_span(span);
1106}
1107
1108pub fn walk_flat_map_where_predicate<T: MutVisitor>(
1109    vis: &mut T,
1110    mut pred: WherePredicate,
1111) -> SmallVec<[WherePredicate; 1]> {
1112    let WherePredicate { attrs, kind, id, span, is_placeholder: _ } = &mut pred;
1113    vis.visit_id(id);
1114    visit_attrs(vis, attrs);
1115    vis.visit_where_predicate_kind(kind);
1116    vis.visit_span(span);
1117    smallvec![pred]
1118}
1119
1120pub fn walk_where_predicate_kind<T: MutVisitor>(vis: &mut T, kind: &mut WherePredicateKind) {
1121    match kind {
1122        WherePredicateKind::BoundPredicate(bp) => {
1123            let WhereBoundPredicate { bound_generic_params, bounded_ty, bounds } = bp;
1124            bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
1125            vis.visit_ty(bounded_ty);
1126            visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound));
1127        }
1128        WherePredicateKind::RegionPredicate(rp) => {
1129            let WhereRegionPredicate { lifetime, bounds } = rp;
1130            vis.visit_lifetime(lifetime);
1131            visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound));
1132        }
1133        WherePredicateKind::EqPredicate(ep) => {
1134            let WhereEqPredicate { lhs_ty, rhs_ty } = ep;
1135            vis.visit_ty(lhs_ty);
1136            vis.visit_ty(rhs_ty);
1137        }
1138    }
1139}
1140
1141fn walk_variant_data<T: MutVisitor>(vis: &mut T, vdata: &mut VariantData) {
1142    match vdata {
1143        VariantData::Struct { fields, recovered: _ } => {
1144            fields.flat_map_in_place(|field| vis.flat_map_field_def(field));
1145        }
1146        VariantData::Tuple(fields, id) => {
1147            vis.visit_id(id);
1148            fields.flat_map_in_place(|field| vis.flat_map_field_def(field));
1149        }
1150        VariantData::Unit(id) => vis.visit_id(id),
1151    }
1152}
1153
1154fn walk_trait_ref<T: MutVisitor>(vis: &mut T, TraitRef { path, ref_id }: &mut TraitRef) {
1155    vis.visit_id(ref_id);
1156    vis.visit_path(path);
1157}
1158
1159fn walk_poly_trait_ref<T: MutVisitor>(vis: &mut T, p: &mut PolyTraitRef) {
1160    let PolyTraitRef { bound_generic_params, modifiers, trait_ref, span } = p;
1161    vis.visit_modifiers(modifiers);
1162    bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
1163    vis.visit_trait_ref(trait_ref);
1164    vis.visit_span(span);
1165}
1166
1167fn walk_modifiers<V: MutVisitor>(vis: &mut V, m: &mut TraitBoundModifiers) {
1168    let TraitBoundModifiers { constness, asyncness, polarity } = m;
1169    match constness {
1170        BoundConstness::Never => {}
1171        BoundConstness::Always(span) | BoundConstness::Maybe(span) => vis.visit_span(span),
1172    }
1173    match asyncness {
1174        BoundAsyncness::Normal => {}
1175        BoundAsyncness::Async(span) => vis.visit_span(span),
1176    }
1177    match polarity {
1178        BoundPolarity::Positive => {}
1179        BoundPolarity::Negative(span) | BoundPolarity::Maybe(span) => vis.visit_span(span),
1180    }
1181}
1182
1183pub fn walk_field_def<T: MutVisitor>(visitor: &mut T, fd: &mut FieldDef) {
1184    let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _, safety, default } = fd;
1185    visitor.visit_id(id);
1186    visit_attrs(visitor, attrs);
1187    visitor.visit_vis(vis);
1188    visit_safety(visitor, safety);
1189    visit_opt(ident, |ident| visitor.visit_ident(ident));
1190    visitor.visit_ty(ty);
1191    visit_opt(default, |default| visitor.visit_anon_const(default));
1192    visitor.visit_span(span);
1193}
1194
1195pub fn walk_flat_map_field_def<T: MutVisitor>(
1196    vis: &mut T,
1197    mut fd: FieldDef,
1198) -> SmallVec<[FieldDef; 1]> {
1199    vis.visit_field_def(&mut fd);
1200    smallvec![fd]
1201}
1202
1203pub fn walk_expr_field<T: MutVisitor>(vis: &mut T, f: &mut ExprField) {
1204    let ExprField { ident, expr, span, is_shorthand: _, attrs, id, is_placeholder: _ } = f;
1205    vis.visit_id(id);
1206    visit_attrs(vis, attrs);
1207    vis.visit_ident(ident);
1208    vis.visit_expr(expr);
1209    vis.visit_span(span);
1210}
1211
1212pub fn walk_flat_map_expr_field<T: MutVisitor>(
1213    vis: &mut T,
1214    mut f: ExprField,
1215) -> SmallVec<[ExprField; 1]> {
1216    vis.visit_expr_field(&mut f);
1217    smallvec![f]
1218}
1219
1220fn walk_mt<T: MutVisitor>(vis: &mut T, MutTy { ty, mutbl: _ }: &mut MutTy) {
1221    vis.visit_ty(ty);
1222}
1223
1224pub fn walk_block<T: MutVisitor>(vis: &mut T, block: &mut P<Block>) {
1225    let Block { id, stmts, rules: _, span, tokens } = block.deref_mut();
1226    vis.visit_id(id);
1227    stmts.flat_map_in_place(|stmt| vis.flat_map_stmt(stmt));
1228    visit_lazy_tts(vis, tokens);
1229    vis.visit_span(span);
1230}
1231
1232pub fn walk_item_kind<K: WalkItemKind>(
1233    kind: &mut K,
1234    span: Span,
1235    id: NodeId,
1236    ident: &mut Ident,
1237    visibility: &mut Visibility,
1238    ctxt: K::Ctxt,
1239    vis: &mut impl MutVisitor,
1240) {
1241    kind.walk(span, id, ident, visibility, ctxt, vis)
1242}
1243
1244impl WalkItemKind for ItemKind {
1245    type Ctxt = ();
1246    fn walk(
1247        &mut self,
1248        span: Span,
1249        id: NodeId,
1250        ident: &mut Ident,
1251        visibility: &mut Visibility,
1252        _ctxt: Self::Ctxt,
1253        vis: &mut impl MutVisitor,
1254    ) {
1255        match self {
1256            ItemKind::ExternCrate(_orig_name) => {}
1257            ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree),
1258            ItemKind::Static(box StaticItem {
1259                ty,
1260                safety: _,
1261                mutability: _,
1262                expr,
1263                define_opaque,
1264            }) => {
1265                vis.visit_ty(ty);
1266                visit_opt(expr, |expr| vis.visit_expr(expr));
1267                walk_define_opaques(vis, define_opaque);
1268            }
1269            ItemKind::Const(item) => {
1270                walk_const_item(vis, item);
1271            }
1272            ItemKind::Fn(func) => {
1273                vis.visit_fn(FnKind::Fn(FnCtxt::Free, ident, visibility, &mut *func), span, id);
1274            }
1275            ItemKind::Mod(safety, mod_kind) => {
1276                visit_safety(vis, safety);
1277                match mod_kind {
1278                    ModKind::Loaded(
1279                        items,
1280                        _inline,
1281                        ModSpans { inner_span, inject_use_span },
1282                        _,
1283                    ) => {
1284                        items.flat_map_in_place(|item| vis.flat_map_item(item));
1285                        vis.visit_span(inner_span);
1286                        vis.visit_span(inject_use_span);
1287                    }
1288                    ModKind::Unloaded => {}
1289                }
1290            }
1291            ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
1292            ItemKind::GlobalAsm(asm) => vis.visit_inline_asm(asm),
1293            ItemKind::TyAlias(box TyAlias { defaultness, generics, where_clauses, bounds, ty }) => {
1294                visit_defaultness(vis, defaultness);
1295                vis.visit_generics(generics);
1296                visit_bounds(vis, bounds, BoundKind::Bound);
1297                visit_opt(ty, |ty| vis.visit_ty(ty));
1298                walk_ty_alias_where_clauses(vis, where_clauses);
1299            }
1300            ItemKind::Enum(EnumDef { variants }, generics) => {
1301                vis.visit_generics(generics);
1302                variants.flat_map_in_place(|variant| vis.flat_map_variant(variant));
1303            }
1304            ItemKind::Struct(variant_data, generics) | ItemKind::Union(variant_data, generics) => {
1305                vis.visit_generics(generics);
1306                vis.visit_variant_data(variant_data);
1307            }
1308            ItemKind::Impl(box Impl {
1309                defaultness,
1310                safety,
1311                generics,
1312                constness,
1313                polarity,
1314                of_trait,
1315                self_ty,
1316                items,
1317            }) => {
1318                visit_defaultness(vis, defaultness);
1319                visit_safety(vis, safety);
1320                vis.visit_generics(generics);
1321                visit_constness(vis, constness);
1322                visit_polarity(vis, polarity);
1323                visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref));
1324                vis.visit_ty(self_ty);
1325                items.flat_map_in_place(|item| {
1326                    vis.flat_map_assoc_item(item, AssocCtxt::Impl { of_trait: of_trait.is_some() })
1327                });
1328            }
1329            ItemKind::Trait(box Trait { safety, is_auto: _, generics, bounds, items }) => {
1330                visit_safety(vis, safety);
1331                vis.visit_generics(generics);
1332                visit_bounds(vis, bounds, BoundKind::Bound);
1333                items.flat_map_in_place(|item| vis.flat_map_assoc_item(item, AssocCtxt::Trait));
1334            }
1335            ItemKind::TraitAlias(generics, bounds) => {
1336                vis.visit_generics(generics);
1337                visit_bounds(vis, bounds, BoundKind::Bound);
1338            }
1339            ItemKind::MacCall(m) => vis.visit_mac_call(m),
1340            ItemKind::MacroDef(def) => vis.visit_macro_def(def),
1341            ItemKind::Delegation(box Delegation {
1342                id,
1343                qself,
1344                path,
1345                rename,
1346                body,
1347                from_glob: _,
1348            }) => {
1349                vis.visit_id(id);
1350                vis.visit_qself(qself);
1351                vis.visit_path(path);
1352                if let Some(rename) = rename {
1353                    vis.visit_ident(rename);
1354                }
1355                if let Some(body) = body {
1356                    vis.visit_block(body);
1357                }
1358            }
1359            ItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => {
1360                vis.visit_qself(qself);
1361                vis.visit_path(prefix);
1362                if let Some(suffixes) = suffixes {
1363                    for (ident, rename) in suffixes {
1364                        vis.visit_ident(ident);
1365                        if let Some(rename) = rename {
1366                            vis.visit_ident(rename);
1367                        }
1368                    }
1369                }
1370                if let Some(body) = body {
1371                    vis.visit_block(body);
1372                }
1373            }
1374        }
1375    }
1376}
1377
1378impl WalkItemKind for AssocItemKind {
1379    type Ctxt = AssocCtxt;
1380    fn walk(
1381        &mut self,
1382        span: Span,
1383        id: NodeId,
1384        ident: &mut Ident,
1385        visibility: &mut Visibility,
1386        ctxt: Self::Ctxt,
1387        visitor: &mut impl MutVisitor,
1388    ) {
1389        match self {
1390            AssocItemKind::Const(item) => {
1391                walk_const_item(visitor, item);
1392            }
1393            AssocItemKind::Fn(func) => {
1394                visitor.visit_fn(
1395                    FnKind::Fn(FnCtxt::Assoc(ctxt), ident, visibility, &mut *func),
1396                    span,
1397                    id,
1398                );
1399            }
1400            AssocItemKind::Type(box TyAlias {
1401                defaultness,
1402                generics,
1403                where_clauses,
1404                bounds,
1405                ty,
1406            }) => {
1407                visit_defaultness(visitor, defaultness);
1408                visitor.visit_generics(generics);
1409                visit_bounds(visitor, bounds, BoundKind::Bound);
1410                visit_opt(ty, |ty| visitor.visit_ty(ty));
1411                walk_ty_alias_where_clauses(visitor, where_clauses);
1412            }
1413            AssocItemKind::MacCall(mac) => visitor.visit_mac_call(mac),
1414            AssocItemKind::Delegation(box Delegation {
1415                id,
1416                qself,
1417                path,
1418                rename,
1419                body,
1420                from_glob: _,
1421            }) => {
1422                visitor.visit_id(id);
1423                visitor.visit_qself(qself);
1424                visitor.visit_path(path);
1425                if let Some(rename) = rename {
1426                    visitor.visit_ident(rename);
1427                }
1428                if let Some(body) = body {
1429                    visitor.visit_block(body);
1430                }
1431            }
1432            AssocItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => {
1433                visitor.visit_qself(qself);
1434                visitor.visit_path(prefix);
1435                if let Some(suffixes) = suffixes {
1436                    for (ident, rename) in suffixes {
1437                        visitor.visit_ident(ident);
1438                        if let Some(rename) = rename {
1439                            visitor.visit_ident(rename);
1440                        }
1441                    }
1442                }
1443                if let Some(body) = body {
1444                    visitor.visit_block(body);
1445                }
1446            }
1447        }
1448    }
1449}
1450
1451fn walk_const_item<T: MutVisitor>(vis: &mut T, item: &mut ConstItem) {
1452    let ConstItem { defaultness, generics, ty, expr, define_opaque } = item;
1453    visit_defaultness(vis, defaultness);
1454    vis.visit_generics(generics);
1455    vis.visit_ty(ty);
1456    visit_opt(expr, |expr| vis.visit_expr(expr));
1457    walk_define_opaques(vis, define_opaque);
1458}
1459
1460fn walk_fn_header<T: MutVisitor>(vis: &mut T, header: &mut FnHeader) {
1461    let FnHeader { safety, coroutine_kind, constness, ext: _ } = header;
1462    visit_constness(vis, constness);
1463    coroutine_kind.as_mut().map(|coroutine_kind| vis.visit_coroutine_kind(coroutine_kind));
1464    visit_safety(vis, safety);
1465}
1466
1467pub fn walk_crate<T: MutVisitor>(vis: &mut T, krate: &mut Crate) {
1468    let Crate { attrs, items, spans, id, is_placeholder: _ } = krate;
1469    vis.visit_id(id);
1470    visit_attrs(vis, attrs);
1471    items.flat_map_in_place(|item| vis.flat_map_item(item));
1472    let ModSpans { inner_span, inject_use_span } = spans;
1473    vis.visit_span(inner_span);
1474    vis.visit_span(inject_use_span);
1475}
1476
1477pub fn walk_item(visitor: &mut impl MutVisitor, item: &mut P<Item<impl WalkItemKind<Ctxt = ()>>>) {
1478    walk_item_ctxt(visitor, item, ())
1479}
1480
1481pub fn walk_assoc_item(visitor: &mut impl MutVisitor, item: &mut P<AssocItem>, ctxt: AssocCtxt) {
1482    walk_item_ctxt(visitor, item, ctxt)
1483}
1484
1485fn walk_item_ctxt<K: WalkItemKind>(
1486    visitor: &mut impl MutVisitor,
1487    item: &mut P<Item<K>>,
1488    ctxt: K::Ctxt,
1489) {
1490    let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut();
1491    visitor.visit_id(id);
1492    visit_attrs(visitor, attrs);
1493    visitor.visit_vis(vis);
1494    visitor.visit_ident(ident);
1495    kind.walk(*span, *id, ident, vis, ctxt, visitor);
1496    visit_lazy_tts(visitor, tokens);
1497    visitor.visit_span(span);
1498}
1499
1500pub fn walk_flat_map_item(vis: &mut impl MutVisitor, mut item: P<Item>) -> SmallVec<[P<Item>; 1]> {
1501    vis.visit_item(&mut item);
1502    smallvec![item]
1503}
1504
1505pub fn walk_flat_map_foreign_item(
1506    vis: &mut impl MutVisitor,
1507    mut item: P<ForeignItem>,
1508) -> SmallVec<[P<ForeignItem>; 1]> {
1509    vis.visit_foreign_item(&mut item);
1510    smallvec![item]
1511}
1512
1513pub fn walk_flat_map_assoc_item(
1514    vis: &mut impl MutVisitor,
1515    mut item: P<AssocItem>,
1516    ctxt: AssocCtxt,
1517) -> SmallVec<[P<AssocItem>; 1]> {
1518    vis.visit_assoc_item(&mut item, ctxt);
1519    smallvec![item]
1520}
1521
1522impl WalkItemKind for ForeignItemKind {
1523    type Ctxt = ();
1524    fn walk(
1525        &mut self,
1526        span: Span,
1527        id: NodeId,
1528        ident: &mut Ident,
1529        visibility: &mut Visibility,
1530        _ctxt: Self::Ctxt,
1531        visitor: &mut impl MutVisitor,
1532    ) {
1533        match self {
1534            ForeignItemKind::Static(box StaticItem {
1535                ty,
1536                mutability: _,
1537                expr,
1538                safety: _,
1539                define_opaque,
1540            }) => {
1541                visitor.visit_ty(ty);
1542                visit_opt(expr, |expr| visitor.visit_expr(expr));
1543                walk_define_opaques(visitor, define_opaque);
1544            }
1545            ForeignItemKind::Fn(func) => {
1546                visitor.visit_fn(
1547                    FnKind::Fn(FnCtxt::Foreign, ident, visibility, &mut *func),
1548                    span,
1549                    id,
1550                );
1551            }
1552            ForeignItemKind::TyAlias(box TyAlias {
1553                defaultness,
1554                generics,
1555                where_clauses,
1556                bounds,
1557                ty,
1558            }) => {
1559                visit_defaultness(visitor, defaultness);
1560                visitor.visit_generics(generics);
1561                visit_bounds(visitor, bounds, BoundKind::Bound);
1562                visit_opt(ty, |ty| visitor.visit_ty(ty));
1563                walk_ty_alias_where_clauses(visitor, where_clauses);
1564            }
1565            ForeignItemKind::MacCall(mac) => visitor.visit_mac_call(mac),
1566        }
1567    }
1568}
1569
1570pub fn walk_pat<T: MutVisitor>(vis: &mut T, pat: &mut P<Pat>) {
1571    let Pat { id, kind, span, tokens } = pat.deref_mut();
1572    vis.visit_id(id);
1573    match kind {
1574        PatKind::Err(_guar) => {}
1575        PatKind::Wild | PatKind::Rest | PatKind::Never => {}
1576        PatKind::Ident(_binding_mode, ident, sub) => {
1577            vis.visit_ident(ident);
1578            visit_opt(sub, |sub| vis.visit_pat(sub));
1579        }
1580        PatKind::Expr(e) => vis.visit_expr(e),
1581        PatKind::TupleStruct(qself, path, elems) => {
1582            vis.visit_qself(qself);
1583            vis.visit_path(path);
1584            visit_thin_vec(elems, |elem| vis.visit_pat(elem));
1585        }
1586        PatKind::Path(qself, path) => {
1587            vis.visit_qself(qself);
1588            vis.visit_path(path);
1589        }
1590        PatKind::Struct(qself, path, fields, _etc) => {
1591            vis.visit_qself(qself);
1592            vis.visit_path(path);
1593            fields.flat_map_in_place(|field| vis.flat_map_pat_field(field));
1594        }
1595        PatKind::Box(inner) => vis.visit_pat(inner),
1596        PatKind::Deref(inner) => vis.visit_pat(inner),
1597        PatKind::Ref(inner, _mutbl) => vis.visit_pat(inner),
1598        PatKind::Range(e1, e2, Spanned { span: _, node: _ }) => {
1599            visit_opt(e1, |e| vis.visit_expr(e));
1600            visit_opt(e2, |e| vis.visit_expr(e));
1601            vis.visit_span(span);
1602        }
1603        PatKind::Guard(p, e) => {
1604            vis.visit_pat(p);
1605            vis.visit_expr(e);
1606        }
1607        PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => {
1608            visit_thin_vec(elems, |elem| vis.visit_pat(elem))
1609        }
1610        PatKind::Paren(inner) => vis.visit_pat(inner),
1611        PatKind::MacCall(mac) => vis.visit_mac_call(mac),
1612    }
1613    visit_lazy_tts(vis, tokens);
1614    vis.visit_span(span);
1615}
1616
1617fn walk_anon_const<T: MutVisitor>(vis: &mut T, AnonConst { id, value }: &mut AnonConst) {
1618    vis.visit_id(id);
1619    vis.visit_expr(value);
1620}
1621
1622fn walk_inline_asm<T: MutVisitor>(vis: &mut T, asm: &mut InlineAsm) {
1623    // FIXME: Visit spans inside all this currently ignored stuff.
1624    let InlineAsm {
1625        asm_macro: _,
1626        template: _,
1627        template_strs: _,
1628        operands,
1629        clobber_abis: _,
1630        options: _,
1631        line_spans: _,
1632    } = asm;
1633    for (op, span) in operands {
1634        match op {
1635            InlineAsmOperand::In { expr, reg: _ }
1636            | InlineAsmOperand::Out { expr: Some(expr), reg: _, late: _ }
1637            | InlineAsmOperand::InOut { expr, reg: _, late: _ } => vis.visit_expr(expr),
1638            InlineAsmOperand::Out { expr: None, reg: _, late: _ } => {}
1639            InlineAsmOperand::SplitInOut { in_expr, out_expr, reg: _, late: _ } => {
1640                vis.visit_expr(in_expr);
1641                if let Some(out_expr) = out_expr {
1642                    vis.visit_expr(out_expr);
1643                }
1644            }
1645            InlineAsmOperand::Const { anon_const } => vis.visit_anon_const(anon_const),
1646            InlineAsmOperand::Sym { sym } => vis.visit_inline_asm_sym(sym),
1647            InlineAsmOperand::Label { block } => vis.visit_block(block),
1648        }
1649        vis.visit_span(span);
1650    }
1651}
1652
1653fn walk_inline_asm_sym<T: MutVisitor>(
1654    vis: &mut T,
1655    InlineAsmSym { id, qself, path }: &mut InlineAsmSym,
1656) {
1657    vis.visit_id(id);
1658    vis.visit_qself(qself);
1659    vis.visit_path(path);
1660}
1661
1662fn walk_format_args<T: MutVisitor>(vis: &mut T, fmt: &mut FormatArgs) {
1663    // FIXME: visit the template exhaustively.
1664    let FormatArgs { span, template: _, arguments, uncooked_fmt_str: _ } = fmt;
1665    for FormatArgument { kind, expr } in arguments.all_args_mut() {
1666        match kind {
1667            FormatArgumentKind::Named(ident) | FormatArgumentKind::Captured(ident) => {
1668                vis.visit_ident(ident)
1669            }
1670            FormatArgumentKind::Normal => {}
1671        }
1672        vis.visit_expr(expr);
1673    }
1674    vis.visit_span(span);
1675}
1676
1677pub fn walk_expr<T: MutVisitor>(vis: &mut T, Expr { kind, id, span, attrs, tokens }: &mut Expr) {
1678    vis.visit_id(id);
1679    visit_attrs(vis, attrs);
1680    match kind {
1681        ExprKind::Array(exprs) => visit_thin_exprs(vis, exprs),
1682        ExprKind::ConstBlock(anon_const) => {
1683            vis.visit_anon_const(anon_const);
1684        }
1685        ExprKind::Repeat(expr, count) => {
1686            vis.visit_expr(expr);
1687            vis.visit_anon_const(count);
1688        }
1689        ExprKind::Tup(exprs) => visit_thin_exprs(vis, exprs),
1690        ExprKind::Call(f, args) => {
1691            vis.visit_expr(f);
1692            visit_thin_exprs(vis, args);
1693        }
1694        ExprKind::MethodCall(box MethodCall {
1695            seg: PathSegment { ident, id, args: seg_args },
1696            receiver,
1697            args: call_args,
1698            span,
1699        }) => {
1700            vis.visit_method_receiver_expr(receiver);
1701            vis.visit_id(id);
1702            vis.visit_ident(ident);
1703            visit_opt(seg_args, |args| vis.visit_generic_args(args));
1704            visit_thin_exprs(vis, call_args);
1705            vis.visit_span(span);
1706        }
1707        ExprKind::Binary(binop, lhs, rhs) => {
1708            vis.visit_expr(lhs);
1709            vis.visit_expr(rhs);
1710            vis.visit_span(&mut binop.span);
1711        }
1712        ExprKind::Unary(_unop, ohs) => vis.visit_expr(ohs),
1713        ExprKind::Cast(expr, ty) => {
1714            vis.visit_expr(expr);
1715            vis.visit_ty(ty);
1716        }
1717        ExprKind::Type(expr, ty) => {
1718            vis.visit_expr(expr);
1719            vis.visit_ty(ty);
1720        }
1721        ExprKind::AddrOf(_kind, _mut, ohs) => vis.visit_expr(ohs),
1722        ExprKind::Let(pat, scrutinee, span, _recovered) => {
1723            vis.visit_pat(pat);
1724            vis.visit_expr(scrutinee);
1725            vis.visit_span(span);
1726        }
1727        ExprKind::If(cond, tr, fl) => {
1728            vis.visit_expr(cond);
1729            vis.visit_block(tr);
1730            visit_opt(fl, |fl| ensure_sufficient_stack(|| vis.visit_expr(fl)));
1731        }
1732        ExprKind::While(cond, body, label) => {
1733            visit_opt(label, |label| vis.visit_label(label));
1734            vis.visit_expr(cond);
1735            vis.visit_block(body);
1736        }
1737        ExprKind::ForLoop { pat, iter, body, label, kind: _ } => {
1738            visit_opt(label, |label| vis.visit_label(label));
1739            vis.visit_pat(pat);
1740            vis.visit_expr(iter);
1741            vis.visit_block(body);
1742        }
1743        ExprKind::Loop(body, label, span) => {
1744            visit_opt(label, |label| vis.visit_label(label));
1745            vis.visit_block(body);
1746            vis.visit_span(span);
1747        }
1748        ExprKind::Match(expr, arms, _kind) => {
1749            vis.visit_expr(expr);
1750            arms.flat_map_in_place(|arm| vis.flat_map_arm(arm));
1751        }
1752        ExprKind::Closure(box Closure {
1753            binder,
1754            capture_clause,
1755            constness,
1756            coroutine_kind,
1757            movability: _,
1758            fn_decl,
1759            body,
1760            fn_decl_span,
1761            fn_arg_span,
1762        }) => {
1763            visit_constness(vis, constness);
1764            vis.visit_capture_by(capture_clause);
1765            vis.visit_fn(FnKind::Closure(binder, coroutine_kind, fn_decl, body), *span, *id);
1766            vis.visit_span(fn_decl_span);
1767            vis.visit_span(fn_arg_span);
1768        }
1769        ExprKind::Block(blk, label) => {
1770            visit_opt(label, |label| vis.visit_label(label));
1771            vis.visit_block(blk);
1772        }
1773        ExprKind::Gen(_capture_by, body, _kind, decl_span) => {
1774            vis.visit_block(body);
1775            vis.visit_span(decl_span);
1776        }
1777        ExprKind::Await(expr, await_kw_span) => {
1778            vis.visit_expr(expr);
1779            vis.visit_span(await_kw_span);
1780        }
1781        ExprKind::Use(expr, use_kw_span) => {
1782            vis.visit_expr(expr);
1783            vis.visit_span(use_kw_span);
1784        }
1785        ExprKind::Assign(el, er, span) => {
1786            vis.visit_expr(el);
1787            vis.visit_expr(er);
1788            vis.visit_span(span);
1789        }
1790        ExprKind::AssignOp(_op, el, er) => {
1791            vis.visit_expr(el);
1792            vis.visit_expr(er);
1793        }
1794        ExprKind::Field(el, ident) => {
1795            vis.visit_expr(el);
1796            vis.visit_ident(ident);
1797        }
1798        ExprKind::Index(el, er, brackets_span) => {
1799            vis.visit_expr(el);
1800            vis.visit_expr(er);
1801            vis.visit_span(brackets_span);
1802        }
1803        ExprKind::Range(e1, e2, _lim) => {
1804            visit_opt(e1, |e1| vis.visit_expr(e1));
1805            visit_opt(e2, |e2| vis.visit_expr(e2));
1806        }
1807        ExprKind::Underscore => {}
1808        ExprKind::Path(qself, path) => {
1809            vis.visit_qself(qself);
1810            vis.visit_path(path);
1811        }
1812        ExprKind::Break(label, expr) => {
1813            visit_opt(label, |label| vis.visit_label(label));
1814            visit_opt(expr, |expr| vis.visit_expr(expr));
1815        }
1816        ExprKind::Continue(label) => {
1817            visit_opt(label, |label| vis.visit_label(label));
1818        }
1819        ExprKind::Ret(expr) => {
1820            visit_opt(expr, |expr| vis.visit_expr(expr));
1821        }
1822        ExprKind::Yeet(expr) => {
1823            visit_opt(expr, |expr| vis.visit_expr(expr));
1824        }
1825        ExprKind::Become(expr) => vis.visit_expr(expr),
1826        ExprKind::InlineAsm(asm) => vis.visit_inline_asm(asm),
1827        ExprKind::FormatArgs(fmt) => vis.visit_format_args(fmt),
1828        ExprKind::OffsetOf(container, fields) => {
1829            vis.visit_ty(container);
1830            for field in fields.iter_mut() {
1831                vis.visit_ident(field);
1832            }
1833        }
1834        ExprKind::MacCall(mac) => vis.visit_mac_call(mac),
1835        ExprKind::Struct(se) => {
1836            let StructExpr { qself, path, fields, rest } = se.deref_mut();
1837            vis.visit_qself(qself);
1838            vis.visit_path(path);
1839            fields.flat_map_in_place(|field| vis.flat_map_expr_field(field));
1840            match rest {
1841                StructRest::Base(expr) => vis.visit_expr(expr),
1842                StructRest::Rest(_span) => {}
1843                StructRest::None => {}
1844            }
1845        }
1846        ExprKind::Paren(expr) => {
1847            vis.visit_expr(expr);
1848        }
1849        ExprKind::Yield(kind) => {
1850            let expr = kind.expr_mut();
1851            if let Some(expr) = expr {
1852                vis.visit_expr(expr);
1853            }
1854        }
1855        ExprKind::Try(expr) => vis.visit_expr(expr),
1856        ExprKind::TryBlock(body) => vis.visit_block(body),
1857        ExprKind::Lit(_token) => {}
1858        ExprKind::IncludedBytes(_bytes) => {}
1859        ExprKind::UnsafeBinderCast(_kind, expr, ty) => {
1860            vis.visit_expr(expr);
1861            if let Some(ty) = ty {
1862                vis.visit_ty(ty);
1863            }
1864        }
1865        ExprKind::Err(_guar) => {}
1866        ExprKind::Dummy => {}
1867    }
1868    visit_lazy_tts(vis, tokens);
1869    vis.visit_span(span);
1870}
1871
1872pub fn noop_filter_map_expr<T: MutVisitor>(vis: &mut T, mut e: P<Expr>) -> Option<P<Expr>> {
1873    Some({
1874        vis.visit_expr(&mut e);
1875        e
1876    })
1877}
1878
1879pub fn walk_flat_map_stmt<T: MutVisitor>(
1880    vis: &mut T,
1881    Stmt { kind, span, mut id }: Stmt,
1882) -> SmallVec<[Stmt; 1]> {
1883    vis.visit_id(&mut id);
1884    let mut stmts: SmallVec<[Stmt; 1]> = walk_flat_map_stmt_kind(vis, kind)
1885        .into_iter()
1886        .map(|kind| Stmt { id, kind, span })
1887        .collect();
1888    match &mut stmts[..] {
1889        [] => {}
1890        [stmt] => vis.visit_span(&mut stmt.span),
1891        _ => panic!(
1892            "cloning statement `NodeId`s is prohibited by default, \
1893             the visitor should implement custom statement visiting"
1894        ),
1895    }
1896    stmts
1897}
1898
1899fn walk_flat_map_stmt_kind<T: MutVisitor>(vis: &mut T, kind: StmtKind) -> SmallVec<[StmtKind; 1]> {
1900    match kind {
1901        StmtKind::Let(mut local) => smallvec![StmtKind::Let({
1902            vis.visit_local(&mut local);
1903            local
1904        })],
1905        StmtKind::Item(item) => vis.flat_map_item(item).into_iter().map(StmtKind::Item).collect(),
1906        StmtKind::Expr(expr) => vis.filter_map_expr(expr).into_iter().map(StmtKind::Expr).collect(),
1907        StmtKind::Semi(expr) => vis.filter_map_expr(expr).into_iter().map(StmtKind::Semi).collect(),
1908        StmtKind::Empty => smallvec![StmtKind::Empty],
1909        StmtKind::MacCall(mut mac) => {
1910            let MacCallStmt { mac: mac_, style: _, attrs, tokens } = mac.deref_mut();
1911            visit_attrs(vis, attrs);
1912            vis.visit_mac_call(mac_);
1913            visit_lazy_tts(vis, tokens);
1914            smallvec![StmtKind::MacCall(mac)]
1915        }
1916    }
1917}
1918
1919fn walk_vis<T: MutVisitor>(vis: &mut T, visibility: &mut Visibility) {
1920    let Visibility { kind, span, tokens } = visibility;
1921    match kind {
1922        VisibilityKind::Public | VisibilityKind::Inherited => {}
1923        VisibilityKind::Restricted { path, id, shorthand: _ } => {
1924            vis.visit_id(id);
1925            vis.visit_path(path);
1926        }
1927    }
1928    visit_lazy_tts(vis, tokens);
1929    vis.visit_span(span);
1930}
1931
1932fn walk_capture_by<T: MutVisitor>(vis: &mut T, capture_by: &mut CaptureBy) {
1933    match capture_by {
1934        CaptureBy::Ref => {}
1935        CaptureBy::Value { move_kw } => {
1936            vis.visit_span(move_kw);
1937        }
1938        CaptureBy::Use { use_kw } => {
1939            vis.visit_span(use_kw);
1940        }
1941    }
1942}
1943
1944fn walk_define_opaques<T: MutVisitor>(
1945    vis: &mut T,
1946    define_opaque: &mut Option<ThinVec<(NodeId, Path)>>,
1947) {
1948    if let Some(define_opaque) = define_opaque {
1949        for (id, path) in define_opaque {
1950            vis.visit_id(id);
1951            vis.visit_path(path)
1952        }
1953    }
1954}
1955
1956/// Some value for the AST node that is valid but possibly meaningless. Similar
1957/// to `Default` but not intended for wide use. The value will never be used
1958/// meaningfully, it exists just to support unwinding in `visit_clobber` in the
1959/// case where its closure panics.
1960pub trait DummyAstNode {
1961    fn dummy() -> Self;
1962}
1963
1964impl<T> DummyAstNode for Option<T> {
1965    fn dummy() -> Self {
1966        Default::default()
1967    }
1968}
1969
1970impl<T: DummyAstNode + 'static> DummyAstNode for P<T> {
1971    fn dummy() -> Self {
1972        P(DummyAstNode::dummy())
1973    }
1974}
1975
1976impl DummyAstNode for Item {
1977    fn dummy() -> Self {
1978        Item {
1979            attrs: Default::default(),
1980            id: DUMMY_NODE_ID,
1981            span: Default::default(),
1982            vis: Visibility {
1983                kind: VisibilityKind::Public,
1984                span: Default::default(),
1985                tokens: Default::default(),
1986            },
1987            ident: Ident::dummy(),
1988            kind: ItemKind::ExternCrate(None),
1989            tokens: Default::default(),
1990        }
1991    }
1992}
1993
1994impl DummyAstNode for Expr {
1995    fn dummy() -> Self {
1996        Expr {
1997            id: DUMMY_NODE_ID,
1998            kind: ExprKind::Dummy,
1999            span: Default::default(),
2000            attrs: Default::default(),
2001            tokens: Default::default(),
2002        }
2003    }
2004}
2005
2006impl DummyAstNode for Ty {
2007    fn dummy() -> Self {
2008        Ty {
2009            id: DUMMY_NODE_ID,
2010            kind: TyKind::Dummy,
2011            span: Default::default(),
2012            tokens: Default::default(),
2013        }
2014    }
2015}
2016
2017impl DummyAstNode for Pat {
2018    fn dummy() -> Self {
2019        Pat {
2020            id: DUMMY_NODE_ID,
2021            kind: PatKind::Wild,
2022            span: Default::default(),
2023            tokens: Default::default(),
2024        }
2025    }
2026}
2027
2028impl DummyAstNode for Stmt {
2029    fn dummy() -> Self {
2030        Stmt { id: DUMMY_NODE_ID, kind: StmtKind::Empty, span: Default::default() }
2031    }
2032}
2033
2034impl DummyAstNode for Crate {
2035    fn dummy() -> Self {
2036        Crate {
2037            attrs: Default::default(),
2038            items: Default::default(),
2039            spans: Default::default(),
2040            id: DUMMY_NODE_ID,
2041            is_placeholder: Default::default(),
2042        }
2043    }
2044}
2045
2046impl<N: DummyAstNode, T: DummyAstNode> DummyAstNode for crate::ast_traits::AstNodeWrapper<N, T> {
2047    fn dummy() -> Self {
2048        crate::ast_traits::AstNodeWrapper::new(N::dummy(), T::dummy())
2049    }
2050}
2051
2052#[derive(Debug)]
2053pub enum FnKind<'a> {
2054    /// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`.
2055    Fn(FnCtxt, &'a mut Ident, &'a mut Visibility, &'a mut Fn),
2056
2057    /// E.g., `|x, y| body`.
2058    Closure(
2059        &'a mut ClosureBinder,
2060        &'a mut Option<CoroutineKind>,
2061        &'a mut P<FnDecl>,
2062        &'a mut P<Expr>,
2063    ),
2064}