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