1use std::ops::DerefMut;
11use std::panic;
12
13use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
14use rustc_data_structures::stack::ensure_sufficient_stack;
15use rustc_span::source_map::Spanned;
16use rustc_span::{Ident, Span};
17use smallvec::{Array, SmallVec, smallvec};
18use thin_vec::ThinVec;
19
20use crate::ast::*;
21use crate::ptr::P;
22use crate::tokenstream::*;
23use crate::visit::{AssocCtxt, BoundKind, FnCtxt, try_visit, visit_opt, walk_list};
24
25pub trait ExpectOne<A: Array> {
26 fn expect_one(self, err: &'static str) -> A::Item;
27}
28
29impl<A: Array> ExpectOne<A> for SmallVec<A> {
30 fn expect_one(self, err: &'static str) -> A::Item {
31 assert!(self.len() == 1, "{}", err);
32 self.into_iter().next().unwrap()
33 }
34}
35
36pub trait MutVisitor: Sized {
37 fn visit_crate(&mut self, c: &mut Crate) {
65 walk_crate(self, c)
66 }
67
68 fn visit_meta_list_item(&mut self, list_item: &mut MetaItemInner) {
69 walk_meta_list_item(self, list_item);
70 }
71
72 fn visit_meta_item(&mut self, meta_item: &mut MetaItem) {
73 walk_meta_item(self, meta_item);
74 }
75
76 fn visit_use_tree(&mut self, use_tree: &mut UseTree) {
77 walk_use_tree(self, use_tree);
78 }
79
80 fn visit_foreign_item(&mut self, ni: &mut ForeignItem) {
81 walk_item(self, ni);
82 }
83
84 fn flat_map_foreign_item(&mut self, ni: P<ForeignItem>) -> SmallVec<[P<ForeignItem>; 1]> {
85 walk_flat_map_foreign_item(self, ni)
86 }
87
88 fn visit_item(&mut self, i: &mut Item) {
89 walk_item(self, i);
90 }
91
92 fn flat_map_item(&mut self, i: P<Item>) -> SmallVec<[P<Item>; 1]> {
93 walk_flat_map_item(self, i)
94 }
95
96 fn visit_fn_header(&mut self, header: &mut FnHeader) {
97 walk_fn_header(self, header);
98 }
99
100 fn visit_field_def(&mut self, fd: &mut FieldDef) {
101 walk_field_def(self, fd);
102 }
103
104 fn flat_map_field_def(&mut self, fd: FieldDef) -> SmallVec<[FieldDef; 1]> {
105 walk_flat_map_field_def(self, fd)
106 }
107
108 fn visit_assoc_item(&mut self, i: &mut AssocItem, ctxt: AssocCtxt) {
109 walk_assoc_item(self, i, ctxt)
110 }
111
112 fn flat_map_assoc_item(
113 &mut self,
114 i: P<AssocItem>,
115 ctxt: AssocCtxt,
116 ) -> SmallVec<[P<AssocItem>; 1]> {
117 walk_flat_map_assoc_item(self, i, ctxt)
118 }
119
120 fn visit_contract(&mut self, c: &mut FnContract) {
121 walk_contract(self, c);
122 }
123
124 fn visit_fn_decl(&mut self, d: &mut FnDecl) {
125 walk_fn_decl(self, d);
126 }
127
128 fn visit_fn(&mut self, fk: FnKind<'_>, _: Span, _: NodeId) {
130 walk_fn(self, fk)
131 }
132
133 fn visit_coroutine_kind(&mut self, a: &mut CoroutineKind) {
134 walk_coroutine_kind(self, a);
135 }
136
137 fn visit_closure_binder(&mut self, b: &mut ClosureBinder) {
138 walk_closure_binder(self, b);
139 }
140
141 fn visit_block(&mut self, b: &mut Block) {
142 walk_block(self, b);
143 }
144
145 fn flat_map_stmt(&mut self, s: Stmt) -> SmallVec<[Stmt; 1]> {
146 walk_flat_map_stmt(self, s)
147 }
148
149 fn visit_arm(&mut self, arm: &mut Arm) {
150 walk_arm(self, arm);
151 }
152
153 fn flat_map_arm(&mut self, arm: Arm) -> SmallVec<[Arm; 1]> {
154 walk_flat_map_arm(self, arm)
155 }
156
157 fn visit_pat(&mut self, p: &mut P<Pat>) {
158 walk_pat(self, p);
159 }
160
161 fn visit_anon_const(&mut self, c: &mut AnonConst) {
162 walk_anon_const(self, c);
163 }
164
165 fn visit_expr(&mut self, e: &mut P<Expr>) {
166 walk_expr(self, e);
167 }
168
169 fn visit_method_receiver_expr(&mut self, ex: &mut P<Expr>) {
172 self.visit_expr(ex)
173 }
174
175 fn filter_map_expr(&mut self, e: P<Expr>) -> Option<P<Expr>> {
176 walk_filter_map_expr(self, e)
177 }
178
179 fn visit_generic_arg(&mut self, arg: &mut GenericArg) {
180 walk_generic_arg(self, arg);
181 }
182
183 fn visit_ty(&mut self, t: &mut P<Ty>) {
184 walk_ty(self, t);
185 }
186
187 fn visit_ty_pat(&mut self, t: &mut TyPat) {
188 walk_ty_pat(self, t);
189 }
190
191 fn visit_lifetime(&mut self, l: &mut Lifetime) {
192 walk_lifetime(self, l);
193 }
194
195 fn visit_assoc_item_constraint(&mut self, c: &mut AssocItemConstraint) {
196 walk_assoc_item_constraint(self, c);
197 }
198
199 fn visit_foreign_mod(&mut self, nm: &mut ForeignMod) {
200 walk_foreign_mod(self, nm);
201 }
202
203 fn visit_variant(&mut self, v: &mut Variant) {
204 walk_variant(self, v);
205 }
206
207 fn flat_map_variant(&mut self, v: Variant) -> SmallVec<[Variant; 1]> {
208 walk_flat_map_variant(self, v)
209 }
210
211 fn visit_ident(&mut self, i: &mut Ident) {
212 walk_ident(self, i);
213 }
214
215 fn visit_modifiers(&mut self, m: &mut TraitBoundModifiers) {
216 walk_modifiers(self, m);
217 }
218
219 fn visit_path(&mut self, p: &mut Path) {
220 walk_path(self, p);
221 }
222
223 fn visit_path_segment(&mut self, p: &mut PathSegment) {
224 walk_path_segment(self, p)
225 }
226
227 fn visit_qself(&mut self, qs: &mut Option<P<QSelf>>) {
228 walk_qself(self, qs);
229 }
230
231 fn visit_generic_args(&mut self, p: &mut GenericArgs) {
232 walk_generic_args(self, p);
233 }
234
235 fn visit_angle_bracketed_parameter_data(&mut self, p: &mut AngleBracketedArgs) {
236 walk_angle_bracketed_parameter_data(self, p);
237 }
238
239 fn visit_parenthesized_parameter_data(&mut self, p: &mut ParenthesizedArgs) {
240 walk_parenthesized_parameter_data(self, p);
241 }
242
243 fn visit_local(&mut self, l: &mut Local) {
244 walk_local(self, l);
245 }
246
247 fn visit_mac_call(&mut self, mac: &mut MacCall) {
248 walk_mac(self, mac);
249 }
250
251 fn visit_macro_def(&mut self, def: &mut MacroDef) {
252 walk_macro_def(self, def);
253 }
254
255 fn visit_label(&mut self, label: &mut Label) {
256 walk_label(self, label);
257 }
258
259 fn visit_attribute(&mut self, at: &mut Attribute) {
260 walk_attribute(self, at);
261 }
262
263 fn visit_param(&mut self, param: &mut Param) {
264 walk_param(self, param);
265 }
266
267 fn flat_map_param(&mut self, param: Param) -> SmallVec<[Param; 1]> {
268 walk_flat_map_param(self, param)
269 }
270
271 fn visit_generics(&mut self, generics: &mut Generics) {
272 walk_generics(self, generics);
273 }
274
275 fn visit_trait_ref(&mut self, tr: &mut TraitRef) {
276 walk_trait_ref(self, tr);
277 }
278
279 fn visit_poly_trait_ref(&mut self, p: &mut PolyTraitRef) {
280 walk_poly_trait_ref(self, p);
281 }
282
283 fn visit_variant_data(&mut self, vdata: &mut VariantData) {
284 walk_variant_data(self, vdata);
285 }
286
287 fn visit_generic_param(&mut self, param: &mut GenericParam) {
288 walk_generic_param(self, param)
289 }
290
291 fn flat_map_generic_param(&mut self, param: GenericParam) -> SmallVec<[GenericParam; 1]> {
292 walk_flat_map_generic_param(self, param)
293 }
294
295 fn visit_param_bound(&mut self, tpb: &mut GenericBound, _ctxt: BoundKind) {
296 walk_param_bound(self, tpb);
297 }
298
299 fn visit_precise_capturing_arg(&mut self, arg: &mut PreciseCapturingArg) {
300 walk_precise_capturing_arg(self, arg);
301 }
302
303 fn visit_expr_field(&mut self, f: &mut ExprField) {
304 walk_expr_field(self, f);
305 }
306
307 fn flat_map_expr_field(&mut self, f: ExprField) -> SmallVec<[ExprField; 1]> {
308 walk_flat_map_expr_field(self, f)
309 }
310
311 fn visit_where_clause(&mut self, where_clause: &mut WhereClause) {
312 walk_where_clause(self, where_clause);
313 }
314
315 fn flat_map_where_predicate(
316 &mut self,
317 where_predicate: WherePredicate,
318 ) -> SmallVec<[WherePredicate; 1]> {
319 walk_flat_map_where_predicate(self, where_predicate)
320 }
321
322 fn visit_where_predicate_kind(&mut self, kind: &mut WherePredicateKind) {
323 walk_where_predicate_kind(self, kind)
324 }
325
326 fn visit_vis(&mut self, vis: &mut Visibility) {
327 walk_vis(self, vis);
328 }
329
330 fn visit_id(&mut self, _id: &mut NodeId) {
331 }
333
334 fn visit_span(&mut self, _sp: &mut Span) {
337 }
339
340 fn visit_pat_field(&mut self, fp: &mut PatField) {
341 walk_pat_field(self, fp)
342 }
343
344 fn flat_map_pat_field(&mut self, fp: PatField) -> SmallVec<[PatField; 1]> {
345 walk_flat_map_pat_field(self, fp)
346 }
347
348 fn visit_inline_asm(&mut self, asm: &mut InlineAsm) {
349 walk_inline_asm(self, asm)
350 }
351
352 fn visit_inline_asm_sym(&mut self, sym: &mut InlineAsmSym) {
353 walk_inline_asm_sym(self, sym)
354 }
355
356 fn visit_format_args(&mut self, fmt: &mut FormatArgs) {
357 walk_format_args(self, fmt)
358 }
359
360 fn visit_capture_by(&mut self, capture_by: &mut CaptureBy) {
361 walk_capture_by(self, capture_by)
362 }
363
364 fn visit_fn_ret_ty(&mut self, fn_ret_ty: &mut FnRetTy) {
365 walk_fn_ret_ty(self, fn_ret_ty)
366 }
367}
368
369super::common_visitor_and_walkers!((mut) MutVisitor);
370
371#[inline]
372fn visit_vec<T, F>(elems: &mut Vec<T>, mut visit_elem: F)
373where
374 F: FnMut(&mut T),
375{
376 for elem in elems {
377 visit_elem(elem);
378 }
379}
380
381#[inline]
382fn visit_thin_vec<T, F>(elems: &mut ThinVec<T>, mut visit_elem: F)
383where
384 F: FnMut(&mut T),
385{
386 for elem in elems {
387 visit_elem(elem);
388 }
389}
390
391#[inline]
392fn visit_opt<T, F>(opt: &mut Option<T>, mut visit_elem: F)
393where
394 F: FnMut(&mut T),
395{
396 if let Some(elem) = opt {
397 visit_elem(elem);
398 }
399}
400
401fn visit_attrs<T: MutVisitor>(vis: &mut T, attrs: &mut AttrVec) {
402 for attr in attrs.iter_mut() {
403 vis.visit_attribute(attr);
404 }
405}
406
407#[allow(unused)]
408fn visit_exprs<T: MutVisitor>(vis: &mut T, exprs: &mut Vec<P<Expr>>) {
409 exprs.flat_map_in_place(|expr| vis.filter_map_expr(expr))
410}
411
412fn visit_thin_exprs<T: MutVisitor>(vis: &mut T, exprs: &mut ThinVec<P<Expr>>) {
413 exprs.flat_map_in_place(|expr| vis.filter_map_expr(expr))
414}
415
416fn visit_attr_args<T: MutVisitor>(vis: &mut T, args: &mut AttrArgs) {
417 match args {
418 AttrArgs::Empty => {}
419 AttrArgs::Delimited(args) => visit_delim_args(vis, args),
420 AttrArgs::Eq { eq_span, expr } => {
421 vis.visit_expr(expr);
422 vis.visit_span(eq_span);
423 }
424 }
425}
426
427fn visit_delim_args<T: MutVisitor>(vis: &mut T, args: &mut DelimArgs) {
428 let DelimArgs { dspan, delim: _, tokens: _ } = args;
429 let DelimSpan { open, close } = dspan;
430 vis.visit_span(open);
431 vis.visit_span(close);
432}
433
434pub fn walk_pat_field<T: MutVisitor>(vis: &mut T, fp: &mut PatField) {
435 let PatField { attrs, id, ident, is_placeholder: _, is_shorthand: _, pat, span } = fp;
436 vis.visit_id(id);
437 visit_attrs(vis, attrs);
438 vis.visit_ident(ident);
439 vis.visit_pat(pat);
440 vis.visit_span(span);
441}
442
443pub fn walk_flat_map_pat_field<T: MutVisitor>(
444 vis: &mut T,
445 mut fp: PatField,
446) -> SmallVec<[PatField; 1]> {
447 vis.visit_pat_field(&mut fp);
448 smallvec![fp]
449}
450
451fn walk_use_tree<T: MutVisitor>(vis: &mut T, use_tree: &mut UseTree) {
452 let UseTree { prefix, kind, span } = use_tree;
453 vis.visit_path(prefix);
454 match kind {
455 UseTreeKind::Simple(rename) => visit_opt(rename, |rename| vis.visit_ident(rename)),
456 UseTreeKind::Nested { items, span } => {
457 for (tree, id) in items {
458 vis.visit_id(id);
459 vis.visit_use_tree(tree);
460 }
461 vis.visit_span(span);
462 }
463 UseTreeKind::Glob => {}
464 }
465 vis.visit_span(span);
466}
467
468pub fn walk_arm<T: MutVisitor>(vis: &mut T, arm: &mut Arm) {
469 let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = arm;
470 vis.visit_id(id);
471 visit_attrs(vis, attrs);
472 vis.visit_pat(pat);
473 visit_opt(guard, |guard| vis.visit_expr(guard));
474 visit_opt(body, |body| vis.visit_expr(body));
475 vis.visit_span(span);
476}
477
478pub fn walk_flat_map_arm<T: MutVisitor>(vis: &mut T, mut arm: Arm) -> SmallVec<[Arm; 1]> {
479 vis.visit_arm(&mut arm);
480 smallvec![arm]
481}
482
483fn walk_assoc_item_constraint<T: MutVisitor>(
484 vis: &mut T,
485 AssocItemConstraint { id, ident, gen_args, kind, span }: &mut AssocItemConstraint,
486) {
487 vis.visit_id(id);
488 vis.visit_ident(ident);
489 if let Some(gen_args) = gen_args {
490 vis.visit_generic_args(gen_args);
491 }
492 match kind {
493 AssocItemConstraintKind::Equality { term } => match term {
494 Term::Ty(ty) => vis.visit_ty(ty),
495 Term::Const(c) => vis.visit_anon_const(c),
496 },
497 AssocItemConstraintKind::Bound { bounds } => visit_bounds(vis, bounds, BoundKind::Bound),
498 }
499 vis.visit_span(span);
500}
501
502pub fn walk_ty<T: MutVisitor>(vis: &mut T, ty: &mut Ty) {
503 let Ty { id, kind, span, tokens: _ } = ty;
504 vis.visit_id(id);
505 match kind {
506 TyKind::Err(_guar) => {}
507 TyKind::Infer | TyKind::ImplicitSelf | TyKind::Dummy | TyKind::Never | TyKind::CVarArgs => {
508 }
509 TyKind::Slice(ty) => vis.visit_ty(ty),
510 TyKind::Ptr(MutTy { ty, mutbl: _ }) => vis.visit_ty(ty),
511 TyKind::Ref(lt, MutTy { ty, mutbl: _ }) | TyKind::PinnedRef(lt, MutTy { ty, mutbl: _ }) => {
512 visit_opt(lt, |lt| vis.visit_lifetime(lt));
513 vis.visit_ty(ty);
514 }
515 TyKind::BareFn(bft) => {
516 let BareFnTy { safety, ext: _, generic_params, decl, decl_span } = bft.deref_mut();
517 visit_safety(vis, safety);
518 generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
519 vis.visit_fn_decl(decl);
520 vis.visit_span(decl_span);
521 }
522 TyKind::UnsafeBinder(binder) => {
523 let UnsafeBinderTy { generic_params, inner_ty } = binder.deref_mut();
524 generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
525 vis.visit_ty(inner_ty);
526 }
527 TyKind::Tup(tys) => visit_thin_vec(tys, |ty| vis.visit_ty(ty)),
528 TyKind::Paren(ty) => vis.visit_ty(ty),
529 TyKind::Pat(ty, pat) => {
530 vis.visit_ty(ty);
531 vis.visit_ty_pat(pat);
532 }
533 TyKind::Path(qself, path) => {
534 vis.visit_qself(qself);
535 vis.visit_path(path);
536 }
537 TyKind::Array(ty, length) => {
538 vis.visit_ty(ty);
539 vis.visit_anon_const(length);
540 }
541 TyKind::Typeof(expr) => vis.visit_anon_const(expr),
542 TyKind::TraitObject(bounds, _syntax) => {
543 visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::TraitObject))
544 }
545 TyKind::ImplTrait(id, bounds) => {
546 vis.visit_id(id);
547 visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Impl));
548 }
549 TyKind::MacCall(mac) => vis.visit_mac_call(mac),
550 }
551 vis.visit_span(span);
552}
553
554pub fn walk_ty_pat<T: MutVisitor>(vis: &mut T, ty: &mut TyPat) {
555 let TyPat { id, kind, span, tokens: _ } = ty;
556 vis.visit_id(id);
557 match kind {
558 TyPatKind::Range(start, end, _include_end) => {
559 visit_opt(start, |c| vis.visit_anon_const(c));
560 visit_opt(end, |c| vis.visit_anon_const(c));
561 }
562 TyPatKind::Or(variants) => visit_thin_vec(variants, |p| vis.visit_ty_pat(p)),
563 TyPatKind::Err(_) => {}
564 }
565 vis.visit_span(span);
566}
567
568pub fn walk_variant<T: MutVisitor>(visitor: &mut T, variant: &mut Variant) {
569 let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = variant;
570 visitor.visit_id(id);
571 visit_attrs(visitor, attrs);
572 visitor.visit_vis(vis);
573 visitor.visit_ident(ident);
574 visitor.visit_variant_data(data);
575 visit_opt(disr_expr, |disr_expr| visitor.visit_anon_const(disr_expr));
576 visitor.visit_span(span);
577}
578
579pub fn walk_flat_map_variant<T: MutVisitor>(
580 vis: &mut T,
581 mut variant: Variant,
582) -> SmallVec<[Variant; 1]> {
583 vis.visit_variant(&mut variant);
584 smallvec![variant]
585}
586
587fn walk_ident<T: MutVisitor>(vis: &mut T, Ident { name: _, span }: &mut Ident) {
588 vis.visit_span(span);
589}
590
591fn walk_path_segment<T: MutVisitor>(vis: &mut T, segment: &mut PathSegment) {
592 let PathSegment { ident, id, args } = segment;
593 vis.visit_id(id);
594 vis.visit_ident(ident);
595 visit_opt(args, |args| vis.visit_generic_args(args));
596}
597
598fn walk_path<T: MutVisitor>(vis: &mut T, Path { segments, span, tokens: _ }: &mut Path) {
599 for segment in segments {
600 vis.visit_path_segment(segment);
601 }
602 vis.visit_span(span);
603}
604
605fn walk_qself<T: MutVisitor>(vis: &mut T, qself: &mut Option<P<QSelf>>) {
606 visit_opt(qself, |qself| {
607 let QSelf { ty, path_span, position: _ } = &mut **qself;
608 vis.visit_ty(ty);
609 vis.visit_span(path_span);
610 })
611}
612
613fn walk_generic_args<T: MutVisitor>(vis: &mut T, generic_args: &mut GenericArgs) {
614 match generic_args {
615 GenericArgs::AngleBracketed(data) => vis.visit_angle_bracketed_parameter_data(data),
616 GenericArgs::Parenthesized(data) => vis.visit_parenthesized_parameter_data(data),
617 GenericArgs::ParenthesizedElided(span) => vis.visit_span(span),
618 }
619}
620
621fn walk_generic_arg<T: MutVisitor>(vis: &mut T, arg: &mut GenericArg) {
622 match arg {
623 GenericArg::Lifetime(lt) => vis.visit_lifetime(lt),
624 GenericArg::Type(ty) => vis.visit_ty(ty),
625 GenericArg::Const(ct) => vis.visit_anon_const(ct),
626 }
627}
628
629fn walk_angle_bracketed_parameter_data<T: MutVisitor>(vis: &mut T, data: &mut AngleBracketedArgs) {
630 let AngleBracketedArgs { args, span } = data;
631 visit_thin_vec(args, |arg| match arg {
632 AngleBracketedArg::Arg(arg) => vis.visit_generic_arg(arg),
633 AngleBracketedArg::Constraint(constraint) => vis.visit_assoc_item_constraint(constraint),
634 });
635 vis.visit_span(span);
636}
637
638fn walk_parenthesized_parameter_data<T: MutVisitor>(vis: &mut T, args: &mut ParenthesizedArgs) {
639 let ParenthesizedArgs { inputs, output, span, inputs_span } = args;
640 visit_thin_vec(inputs, |input| vis.visit_ty(input));
641 vis.visit_fn_ret_ty(output);
642 vis.visit_span(span);
643 vis.visit_span(inputs_span);
644}
645
646fn walk_local<T: MutVisitor>(vis: &mut T, local: &mut Local) {
647 let Local { id, super_, pat, ty, kind, span, colon_sp, attrs, tokens: _ } = local;
648 visit_opt(super_, |sp| vis.visit_span(sp));
649 vis.visit_id(id);
650 visit_attrs(vis, attrs);
651 vis.visit_pat(pat);
652 visit_opt(ty, |ty| vis.visit_ty(ty));
653 match kind {
654 LocalKind::Decl => {}
655 LocalKind::Init(init) => {
656 vis.visit_expr(init);
657 }
658 LocalKind::InitElse(init, els) => {
659 vis.visit_expr(init);
660 vis.visit_block(els);
661 }
662 }
663 visit_opt(colon_sp, |sp| vis.visit_span(sp));
664 vis.visit_span(span);
665}
666
667fn walk_attribute<T: MutVisitor>(vis: &mut T, attr: &mut Attribute) {
668 let Attribute { kind, id: _, style: _, span } = attr;
669 match kind {
670 AttrKind::Normal(normal) => {
671 let NormalAttr { item: AttrItem { unsafety: _, path, args, tokens: _ }, tokens: _ } =
672 &mut **normal;
673 vis.visit_path(path);
674 visit_attr_args(vis, args);
675 }
676 AttrKind::DocComment(_kind, _sym) => {}
677 }
678 vis.visit_span(span);
679}
680
681fn walk_mac<T: MutVisitor>(vis: &mut T, mac: &mut MacCall) {
682 let MacCall { path, args } = mac;
683 vis.visit_path(path);
684 visit_delim_args(vis, args);
685}
686
687fn walk_macro_def<T: MutVisitor>(vis: &mut T, macro_def: &mut MacroDef) {
688 let MacroDef { body, macro_rules: _ } = macro_def;
689 visit_delim_args(vis, body);
690}
691
692fn walk_meta_list_item<T: MutVisitor>(vis: &mut T, li: &mut MetaItemInner) {
693 match li {
694 MetaItemInner::MetaItem(mi) => vis.visit_meta_item(mi),
695 MetaItemInner::Lit(_lit) => {}
696 }
697}
698
699fn walk_meta_item<T: MutVisitor>(vis: &mut T, mi: &mut MetaItem) {
700 let MetaItem { unsafety: _, path: _, kind, span } = mi;
701 match kind {
702 MetaItemKind::Word => {}
703 MetaItemKind::List(mis) => visit_thin_vec(mis, |mi| vis.visit_meta_list_item(mi)),
704 MetaItemKind::NameValue(_s) => {}
705 }
706 vis.visit_span(span);
707}
708
709pub fn walk_param<T: MutVisitor>(vis: &mut T, param: &mut Param) {
710 let Param { attrs, id, pat, span, ty, is_placeholder: _ } = param;
711 vis.visit_id(id);
712 visit_attrs(vis, attrs);
713 vis.visit_pat(pat);
714 vis.visit_ty(ty);
715 vis.visit_span(span);
716}
717
718pub fn walk_flat_map_param<T: MutVisitor>(vis: &mut T, mut param: Param) -> SmallVec<[Param; 1]> {
719 vis.visit_param(&mut param);
720 smallvec![param]
721}
722
723fn walk_closure_binder<T: MutVisitor>(vis: &mut T, binder: &mut ClosureBinder) {
724 match binder {
725 ClosureBinder::NotPresent => {}
726 ClosureBinder::For { span: _, generic_params } => {
727 generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
728 }
729 }
730}
731
732fn walk_coroutine_kind<T: MutVisitor>(vis: &mut T, coroutine_kind: &mut CoroutineKind) {
733 match coroutine_kind {
734 CoroutineKind::Async { span, closure_id, return_impl_trait_id }
735 | CoroutineKind::Gen { span, closure_id, return_impl_trait_id }
736 | CoroutineKind::AsyncGen { span, closure_id, return_impl_trait_id } => {
737 vis.visit_id(closure_id);
738 vis.visit_id(return_impl_trait_id);
739 vis.visit_span(span);
740 }
741 }
742}
743
744fn walk_fn<T: MutVisitor>(vis: &mut T, kind: FnKind<'_>) {
745 match kind {
746 FnKind::Fn(
747 _ctxt,
748 _vis,
749 Fn {
750 defaultness,
751 ident,
752 generics,
753 contract,
754 body,
755 sig: FnSig { header, decl, span },
756 define_opaque,
757 },
758 ) => {
759 visit_defaultness(vis, defaultness);
761 vis.visit_ident(ident);
762 vis.visit_fn_header(header);
763 vis.visit_generics(generics);
764 vis.visit_fn_decl(decl);
765 if let Some(contract) = contract {
766 vis.visit_contract(contract);
767 }
768 if let Some(body) = body {
769 vis.visit_block(body);
770 }
771 vis.visit_span(span);
772
773 walk_define_opaques(vis, define_opaque);
774 }
775 FnKind::Closure(binder, coroutine_kind, decl, body) => {
776 vis.visit_closure_binder(binder);
777 coroutine_kind.as_mut().map(|coroutine_kind| vis.visit_coroutine_kind(coroutine_kind));
778 vis.visit_fn_decl(decl);
779 vis.visit_expr(body);
780 }
781 }
782}
783
784fn walk_contract<T: MutVisitor>(vis: &mut T, contract: &mut FnContract) {
785 let FnContract { requires, ensures } = contract;
786 if let Some(pred) = requires {
787 vis.visit_expr(pred);
788 }
789 if let Some(pred) = ensures {
790 vis.visit_expr(pred);
791 }
792}
793
794fn walk_fn_decl<T: MutVisitor>(vis: &mut T, decl: &mut FnDecl) {
795 let FnDecl { inputs, output } = decl;
796 inputs.flat_map_in_place(|param| vis.flat_map_param(param));
797 vis.visit_fn_ret_ty(output);
798}
799
800fn walk_fn_ret_ty<T: MutVisitor>(vis: &mut T, fn_ret_ty: &mut FnRetTy) {
801 match fn_ret_ty {
802 FnRetTy::Default(span) => vis.visit_span(span),
803 FnRetTy::Ty(ty) => vis.visit_ty(ty),
804 }
805}
806
807fn walk_param_bound<T: MutVisitor>(vis: &mut T, pb: &mut GenericBound) {
808 match pb {
809 GenericBound::Trait(trait_ref) => vis.visit_poly_trait_ref(trait_ref),
810 GenericBound::Outlives(lifetime) => walk_lifetime(vis, lifetime),
811 GenericBound::Use(args, span) => {
812 for arg in args {
813 vis.visit_precise_capturing_arg(arg);
814 }
815 vis.visit_span(span);
816 }
817 }
818}
819
820fn walk_precise_capturing_arg<T: MutVisitor>(vis: &mut T, arg: &mut PreciseCapturingArg) {
821 match arg {
822 PreciseCapturingArg::Lifetime(lt) => {
823 vis.visit_lifetime(lt);
824 }
825 PreciseCapturingArg::Arg(path, id) => {
826 vis.visit_id(id);
827 vis.visit_path(path);
828 }
829 }
830}
831
832pub fn walk_generic_param<T: MutVisitor>(vis: &mut T, param: &mut GenericParam) {
833 let GenericParam { id, ident, attrs, bounds, kind, colon_span, is_placeholder: _ } = param;
834 vis.visit_id(id);
835 visit_attrs(vis, attrs);
836 vis.visit_ident(ident);
837 visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound));
838 match kind {
839 GenericParamKind::Lifetime => {}
840 GenericParamKind::Type { default } => {
841 visit_opt(default, |default| vis.visit_ty(default));
842 }
843 GenericParamKind::Const { ty, kw_span: _, default } => {
844 vis.visit_ty(ty);
845 visit_opt(default, |default| vis.visit_anon_const(default));
846 }
847 }
848 if let Some(colon_span) = colon_span {
849 vis.visit_span(colon_span);
850 }
851}
852
853pub fn walk_flat_map_generic_param<T: MutVisitor>(
854 vis: &mut T,
855 mut param: GenericParam,
856) -> SmallVec<[GenericParam; 1]> {
857 vis.visit_generic_param(&mut param);
858 smallvec![param]
859}
860
861fn walk_generics<T: MutVisitor>(vis: &mut T, generics: &mut Generics) {
862 let Generics { params, where_clause, span } = generics;
863 params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
864 vis.visit_where_clause(where_clause);
865 vis.visit_span(span);
866}
867
868fn walk_ty_alias_where_clauses<T: MutVisitor>(vis: &mut T, tawcs: &mut TyAliasWhereClauses) {
869 let TyAliasWhereClauses { before, after, split: _ } = tawcs;
870 let TyAliasWhereClause { has_where_token: _, span: span_before } = before;
871 let TyAliasWhereClause { has_where_token: _, span: span_after } = after;
872 vis.visit_span(span_before);
873 vis.visit_span(span_after);
874}
875
876fn walk_where_clause<T: MutVisitor>(vis: &mut T, wc: &mut WhereClause) {
877 let WhereClause { has_where_token: _, predicates, span } = wc;
878 predicates.flat_map_in_place(|predicate| vis.flat_map_where_predicate(predicate));
879 vis.visit_span(span);
880}
881
882pub fn walk_flat_map_where_predicate<T: MutVisitor>(
883 vis: &mut T,
884 mut pred: WherePredicate,
885) -> SmallVec<[WherePredicate; 1]> {
886 let WherePredicate { attrs, kind, id, span, is_placeholder: _ } = &mut pred;
887 vis.visit_id(id);
888 visit_attrs(vis, attrs);
889 vis.visit_where_predicate_kind(kind);
890 vis.visit_span(span);
891 smallvec![pred]
892}
893
894pub fn walk_where_predicate_kind<T: MutVisitor>(vis: &mut T, kind: &mut WherePredicateKind) {
895 match kind {
896 WherePredicateKind::BoundPredicate(bp) => {
897 let WhereBoundPredicate { bound_generic_params, bounded_ty, bounds } = bp;
898 bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
899 vis.visit_ty(bounded_ty);
900 visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound));
901 }
902 WherePredicateKind::RegionPredicate(rp) => {
903 let WhereRegionPredicate { lifetime, bounds } = rp;
904 vis.visit_lifetime(lifetime);
905 visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound));
906 }
907 WherePredicateKind::EqPredicate(ep) => {
908 let WhereEqPredicate { lhs_ty, rhs_ty } = ep;
909 vis.visit_ty(lhs_ty);
910 vis.visit_ty(rhs_ty);
911 }
912 }
913}
914
915fn walk_variant_data<T: MutVisitor>(vis: &mut T, vdata: &mut VariantData) {
916 match vdata {
917 VariantData::Struct { fields, recovered: _ } => {
918 fields.flat_map_in_place(|field| vis.flat_map_field_def(field));
919 }
920 VariantData::Tuple(fields, id) => {
921 vis.visit_id(id);
922 fields.flat_map_in_place(|field| vis.flat_map_field_def(field));
923 }
924 VariantData::Unit(id) => vis.visit_id(id),
925 }
926}
927
928fn walk_trait_ref<T: MutVisitor>(vis: &mut T, TraitRef { path, ref_id }: &mut TraitRef) {
929 vis.visit_id(ref_id);
930 vis.visit_path(path);
931}
932
933fn walk_poly_trait_ref<T: MutVisitor>(vis: &mut T, p: &mut PolyTraitRef) {
934 let PolyTraitRef { bound_generic_params, modifiers, trait_ref, span } = p;
935 vis.visit_modifiers(modifiers);
936 bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
937 vis.visit_trait_ref(trait_ref);
938 vis.visit_span(span);
939}
940
941fn walk_modifiers<V: MutVisitor>(vis: &mut V, m: &mut TraitBoundModifiers) {
942 let TraitBoundModifiers { constness, asyncness, polarity } = m;
943 match constness {
944 BoundConstness::Never => {}
945 BoundConstness::Always(span) | BoundConstness::Maybe(span) => vis.visit_span(span),
946 }
947 match asyncness {
948 BoundAsyncness::Normal => {}
949 BoundAsyncness::Async(span) => vis.visit_span(span),
950 }
951 match polarity {
952 BoundPolarity::Positive => {}
953 BoundPolarity::Negative(span) | BoundPolarity::Maybe(span) => vis.visit_span(span),
954 }
955}
956
957pub fn walk_field_def<T: MutVisitor>(visitor: &mut T, fd: &mut FieldDef) {
958 let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _, safety, default } = fd;
959 visitor.visit_id(id);
960 visit_attrs(visitor, attrs);
961 visitor.visit_vis(vis);
962 visit_safety(visitor, safety);
963 visit_opt(ident, |ident| visitor.visit_ident(ident));
964 visitor.visit_ty(ty);
965 visit_opt(default, |default| visitor.visit_anon_const(default));
966 visitor.visit_span(span);
967}
968
969pub fn walk_flat_map_field_def<T: MutVisitor>(
970 vis: &mut T,
971 mut fd: FieldDef,
972) -> SmallVec<[FieldDef; 1]> {
973 vis.visit_field_def(&mut fd);
974 smallvec![fd]
975}
976
977pub fn walk_expr_field<T: MutVisitor>(vis: &mut T, f: &mut ExprField) {
978 let ExprField { ident, expr, span, is_shorthand: _, attrs, id, is_placeholder: _ } = f;
979 vis.visit_id(id);
980 visit_attrs(vis, attrs);
981 vis.visit_ident(ident);
982 vis.visit_expr(expr);
983 vis.visit_span(span);
984}
985
986pub fn walk_flat_map_expr_field<T: MutVisitor>(
987 vis: &mut T,
988 mut f: ExprField,
989) -> SmallVec<[ExprField; 1]> {
990 vis.visit_expr_field(&mut f);
991 smallvec![f]
992}
993
994pub fn walk_block<T: MutVisitor>(vis: &mut T, block: &mut Block) {
995 let Block { id, stmts, rules: _, span, tokens: _ } = block;
996 vis.visit_id(id);
997 stmts.flat_map_in_place(|stmt| vis.flat_map_stmt(stmt));
998 vis.visit_span(span);
999}
1000
1001pub fn walk_item_kind<K: WalkItemKind>(
1002 kind: &mut K,
1003 span: Span,
1004 id: NodeId,
1005 visibility: &mut Visibility,
1006 ctxt: K::Ctxt,
1007 vis: &mut impl MutVisitor,
1008) {
1009 kind.walk(span, id, visibility, ctxt, vis)
1010}
1011
1012pub fn walk_crate<T: MutVisitor>(vis: &mut T, krate: &mut Crate) {
1013 let Crate { attrs, items, spans, id, is_placeholder: _ } = krate;
1014 vis.visit_id(id);
1015 visit_attrs(vis, attrs);
1016 items.flat_map_in_place(|item| vis.flat_map_item(item));
1017 let ModSpans { inner_span, inject_use_span } = spans;
1018 vis.visit_span(inner_span);
1019 vis.visit_span(inject_use_span);
1020}
1021
1022pub fn walk_flat_map_item(vis: &mut impl MutVisitor, mut item: P<Item>) -> SmallVec<[P<Item>; 1]> {
1023 vis.visit_item(&mut item);
1024 smallvec![item]
1025}
1026
1027pub fn walk_flat_map_foreign_item(
1028 vis: &mut impl MutVisitor,
1029 mut item: P<ForeignItem>,
1030) -> SmallVec<[P<ForeignItem>; 1]> {
1031 vis.visit_foreign_item(&mut item);
1032 smallvec![item]
1033}
1034
1035pub fn walk_flat_map_assoc_item(
1036 vis: &mut impl MutVisitor,
1037 mut item: P<AssocItem>,
1038 ctxt: AssocCtxt,
1039) -> SmallVec<[P<AssocItem>; 1]> {
1040 vis.visit_assoc_item(&mut item, ctxt);
1041 smallvec![item]
1042}
1043
1044pub fn walk_pat<T: MutVisitor>(vis: &mut T, pat: &mut Pat) {
1045 let Pat { id, kind, span, tokens: _ } = pat;
1046 vis.visit_id(id);
1047 match kind {
1048 PatKind::Err(_guar) => {}
1049 PatKind::Missing | PatKind::Wild | PatKind::Rest | PatKind::Never => {}
1050 PatKind::Ident(_binding_mode, ident, sub) => {
1051 vis.visit_ident(ident);
1052 visit_opt(sub, |sub| vis.visit_pat(sub));
1053 }
1054 PatKind::Expr(e) => vis.visit_expr(e),
1055 PatKind::TupleStruct(qself, path, elems) => {
1056 vis.visit_qself(qself);
1057 vis.visit_path(path);
1058 visit_thin_vec(elems, |elem| vis.visit_pat(elem));
1059 }
1060 PatKind::Path(qself, path) => {
1061 vis.visit_qself(qself);
1062 vis.visit_path(path);
1063 }
1064 PatKind::Struct(qself, path, fields, _etc) => {
1065 vis.visit_qself(qself);
1066 vis.visit_path(path);
1067 fields.flat_map_in_place(|field| vis.flat_map_pat_field(field));
1068 }
1069 PatKind::Box(inner) => vis.visit_pat(inner),
1070 PatKind::Deref(inner) => vis.visit_pat(inner),
1071 PatKind::Ref(inner, _mutbl) => vis.visit_pat(inner),
1072 PatKind::Range(e1, e2, Spanned { span: _, node: _ }) => {
1073 visit_opt(e1, |e| vis.visit_expr(e));
1074 visit_opt(e2, |e| vis.visit_expr(e));
1075 vis.visit_span(span);
1076 }
1077 PatKind::Guard(p, e) => {
1078 vis.visit_pat(p);
1079 vis.visit_expr(e);
1080 }
1081 PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => {
1082 visit_thin_vec(elems, |elem| vis.visit_pat(elem))
1083 }
1084 PatKind::Paren(inner) => vis.visit_pat(inner),
1085 PatKind::MacCall(mac) => vis.visit_mac_call(mac),
1086 }
1087 vis.visit_span(span);
1088}
1089
1090fn walk_anon_const<T: MutVisitor>(vis: &mut T, AnonConst { id, value }: &mut AnonConst) {
1091 vis.visit_id(id);
1092 vis.visit_expr(value);
1093}
1094
1095fn walk_inline_asm<T: MutVisitor>(vis: &mut T, asm: &mut InlineAsm) {
1096 let InlineAsm {
1098 asm_macro: _,
1099 template: _,
1100 template_strs: _,
1101 operands,
1102 clobber_abis: _,
1103 options: _,
1104 line_spans: _,
1105 } = asm;
1106 for (op, span) in operands {
1107 match op {
1108 InlineAsmOperand::In { expr, reg: _ }
1109 | InlineAsmOperand::Out { expr: Some(expr), reg: _, late: _ }
1110 | InlineAsmOperand::InOut { expr, reg: _, late: _ } => vis.visit_expr(expr),
1111 InlineAsmOperand::Out { expr: None, reg: _, late: _ } => {}
1112 InlineAsmOperand::SplitInOut { in_expr, out_expr, reg: _, late: _ } => {
1113 vis.visit_expr(in_expr);
1114 if let Some(out_expr) = out_expr {
1115 vis.visit_expr(out_expr);
1116 }
1117 }
1118 InlineAsmOperand::Const { anon_const } => vis.visit_anon_const(anon_const),
1119 InlineAsmOperand::Sym { sym } => vis.visit_inline_asm_sym(sym),
1120 InlineAsmOperand::Label { block } => vis.visit_block(block),
1121 }
1122 vis.visit_span(span);
1123 }
1124}
1125
1126fn walk_inline_asm_sym<T: MutVisitor>(
1127 vis: &mut T,
1128 InlineAsmSym { id, qself, path }: &mut InlineAsmSym,
1129) {
1130 vis.visit_id(id);
1131 vis.visit_qself(qself);
1132 vis.visit_path(path);
1133}
1134
1135fn walk_format_args<T: MutVisitor>(vis: &mut T, fmt: &mut FormatArgs) {
1136 let FormatArgs { span, template: _, arguments, uncooked_fmt_str: _ } = fmt;
1138 for FormatArgument { kind, expr } in arguments.all_args_mut() {
1139 match kind {
1140 FormatArgumentKind::Named(ident) | FormatArgumentKind::Captured(ident) => {
1141 vis.visit_ident(ident)
1142 }
1143 FormatArgumentKind::Normal => {}
1144 }
1145 vis.visit_expr(expr);
1146 }
1147 vis.visit_span(span);
1148}
1149
1150pub fn walk_expr<T: MutVisitor>(vis: &mut T, Expr { kind, id, span, attrs, tokens: _ }: &mut Expr) {
1151 vis.visit_id(id);
1152 visit_attrs(vis, attrs);
1153 match kind {
1154 ExprKind::Array(exprs) => visit_thin_exprs(vis, exprs),
1155 ExprKind::ConstBlock(anon_const) => {
1156 vis.visit_anon_const(anon_const);
1157 }
1158 ExprKind::Repeat(expr, count) => {
1159 vis.visit_expr(expr);
1160 vis.visit_anon_const(count);
1161 }
1162 ExprKind::Tup(exprs) => visit_thin_exprs(vis, exprs),
1163 ExprKind::Call(f, args) => {
1164 vis.visit_expr(f);
1165 visit_thin_exprs(vis, args);
1166 }
1167 ExprKind::MethodCall(box MethodCall {
1168 seg: PathSegment { ident, id, args: seg_args },
1169 receiver,
1170 args: call_args,
1171 span,
1172 }) => {
1173 vis.visit_method_receiver_expr(receiver);
1174 vis.visit_id(id);
1175 vis.visit_ident(ident);
1176 visit_opt(seg_args, |args| vis.visit_generic_args(args));
1177 visit_thin_exprs(vis, call_args);
1178 vis.visit_span(span);
1179 }
1180 ExprKind::Binary(binop, lhs, rhs) => {
1181 vis.visit_expr(lhs);
1182 vis.visit_expr(rhs);
1183 vis.visit_span(&mut binop.span);
1184 }
1185 ExprKind::Unary(_unop, ohs) => vis.visit_expr(ohs),
1186 ExprKind::Cast(expr, ty) => {
1187 vis.visit_expr(expr);
1188 vis.visit_ty(ty);
1189 }
1190 ExprKind::Type(expr, ty) => {
1191 vis.visit_expr(expr);
1192 vis.visit_ty(ty);
1193 }
1194 ExprKind::AddrOf(_kind, _mut, ohs) => vis.visit_expr(ohs),
1195 ExprKind::Let(pat, scrutinee, span, _recovered) => {
1196 vis.visit_pat(pat);
1197 vis.visit_expr(scrutinee);
1198 vis.visit_span(span);
1199 }
1200 ExprKind::If(cond, tr, fl) => {
1201 vis.visit_expr(cond);
1202 vis.visit_block(tr);
1203 visit_opt(fl, |fl| ensure_sufficient_stack(|| vis.visit_expr(fl)));
1204 }
1205 ExprKind::While(cond, body, label) => {
1206 visit_opt(label, |label| vis.visit_label(label));
1207 vis.visit_expr(cond);
1208 vis.visit_block(body);
1209 }
1210 ExprKind::ForLoop { pat, iter, body, label, kind: _ } => {
1211 visit_opt(label, |label| vis.visit_label(label));
1212 vis.visit_pat(pat);
1213 vis.visit_expr(iter);
1214 vis.visit_block(body);
1215 }
1216 ExprKind::Loop(body, label, span) => {
1217 visit_opt(label, |label| vis.visit_label(label));
1218 vis.visit_block(body);
1219 vis.visit_span(span);
1220 }
1221 ExprKind::Match(expr, arms, _kind) => {
1222 vis.visit_expr(expr);
1223 arms.flat_map_in_place(|arm| vis.flat_map_arm(arm));
1224 }
1225 ExprKind::Closure(box Closure {
1226 binder,
1227 capture_clause,
1228 constness,
1229 coroutine_kind,
1230 movability: _,
1231 fn_decl,
1232 body,
1233 fn_decl_span,
1234 fn_arg_span,
1235 }) => {
1236 visit_constness(vis, constness);
1237 vis.visit_capture_by(capture_clause);
1238 vis.visit_fn(FnKind::Closure(binder, coroutine_kind, fn_decl, body), *span, *id);
1239 vis.visit_span(fn_decl_span);
1240 vis.visit_span(fn_arg_span);
1241 }
1242 ExprKind::Block(blk, label) => {
1243 visit_opt(label, |label| vis.visit_label(label));
1244 vis.visit_block(blk);
1245 }
1246 ExprKind::Gen(_capture_by, body, _kind, decl_span) => {
1247 vis.visit_block(body);
1248 vis.visit_span(decl_span);
1249 }
1250 ExprKind::Await(expr, await_kw_span) => {
1251 vis.visit_expr(expr);
1252 vis.visit_span(await_kw_span);
1253 }
1254 ExprKind::Use(expr, use_kw_span) => {
1255 vis.visit_expr(expr);
1256 vis.visit_span(use_kw_span);
1257 }
1258 ExprKind::Assign(el, er, span) => {
1259 vis.visit_expr(el);
1260 vis.visit_expr(er);
1261 vis.visit_span(span);
1262 }
1263 ExprKind::AssignOp(_op, el, er) => {
1264 vis.visit_expr(el);
1265 vis.visit_expr(er);
1266 }
1267 ExprKind::Field(el, ident) => {
1268 vis.visit_expr(el);
1269 vis.visit_ident(ident);
1270 }
1271 ExprKind::Index(el, er, brackets_span) => {
1272 vis.visit_expr(el);
1273 vis.visit_expr(er);
1274 vis.visit_span(brackets_span);
1275 }
1276 ExprKind::Range(e1, e2, _lim) => {
1277 visit_opt(e1, |e1| vis.visit_expr(e1));
1278 visit_opt(e2, |e2| vis.visit_expr(e2));
1279 }
1280 ExprKind::Underscore => {}
1281 ExprKind::Path(qself, path) => {
1282 vis.visit_qself(qself);
1283 vis.visit_path(path);
1284 }
1285 ExprKind::Break(label, expr) => {
1286 visit_opt(label, |label| vis.visit_label(label));
1287 visit_opt(expr, |expr| vis.visit_expr(expr));
1288 }
1289 ExprKind::Continue(label) => {
1290 visit_opt(label, |label| vis.visit_label(label));
1291 }
1292 ExprKind::Ret(expr) => {
1293 visit_opt(expr, |expr| vis.visit_expr(expr));
1294 }
1295 ExprKind::Yeet(expr) => {
1296 visit_opt(expr, |expr| vis.visit_expr(expr));
1297 }
1298 ExprKind::Become(expr) => vis.visit_expr(expr),
1299 ExprKind::InlineAsm(asm) => vis.visit_inline_asm(asm),
1300 ExprKind::FormatArgs(fmt) => vis.visit_format_args(fmt),
1301 ExprKind::OffsetOf(container, fields) => {
1302 vis.visit_ty(container);
1303 for field in fields.iter_mut() {
1304 vis.visit_ident(field);
1305 }
1306 }
1307 ExprKind::MacCall(mac) => vis.visit_mac_call(mac),
1308 ExprKind::Struct(se) => {
1309 let StructExpr { qself, path, fields, rest } = se.deref_mut();
1310 vis.visit_qself(qself);
1311 vis.visit_path(path);
1312 fields.flat_map_in_place(|field| vis.flat_map_expr_field(field));
1313 match rest {
1314 StructRest::Base(expr) => vis.visit_expr(expr),
1315 StructRest::Rest(_span) => {}
1316 StructRest::None => {}
1317 }
1318 }
1319 ExprKind::Paren(expr) => {
1320 vis.visit_expr(expr);
1321 }
1322 ExprKind::Yield(kind) => {
1323 let expr = kind.expr_mut();
1324 if let Some(expr) = expr {
1325 vis.visit_expr(expr);
1326 }
1327 }
1328 ExprKind::Try(expr) => vis.visit_expr(expr),
1329 ExprKind::TryBlock(body) => vis.visit_block(body),
1330 ExprKind::Lit(_token) => {}
1331 ExprKind::IncludedBytes(_bytes) => {}
1332 ExprKind::UnsafeBinderCast(_kind, expr, ty) => {
1333 vis.visit_expr(expr);
1334 if let Some(ty) = ty {
1335 vis.visit_ty(ty);
1336 }
1337 }
1338 ExprKind::Err(_guar) => {}
1339 ExprKind::Dummy => {}
1340 }
1341 vis.visit_span(span);
1342}
1343
1344pub fn walk_filter_map_expr<T: MutVisitor>(vis: &mut T, mut e: P<Expr>) -> Option<P<Expr>> {
1345 vis.visit_expr(&mut e);
1346 Some(e)
1347}
1348
1349pub fn walk_flat_map_stmt<T: MutVisitor>(
1350 vis: &mut T,
1351 Stmt { kind, span, mut id }: Stmt,
1352) -> SmallVec<[Stmt; 1]> {
1353 vis.visit_id(&mut id);
1354 let mut stmts: SmallVec<[Stmt; 1]> = walk_flat_map_stmt_kind(vis, kind)
1355 .into_iter()
1356 .map(|kind| Stmt { id, kind, span })
1357 .collect();
1358 match &mut stmts[..] {
1359 [] => {}
1360 [stmt] => vis.visit_span(&mut stmt.span),
1361 _ => panic!(
1362 "cloning statement `NodeId`s is prohibited by default, \
1363 the visitor should implement custom statement visiting"
1364 ),
1365 }
1366 stmts
1367}
1368
1369fn walk_flat_map_stmt_kind<T: MutVisitor>(vis: &mut T, kind: StmtKind) -> SmallVec<[StmtKind; 1]> {
1370 match kind {
1371 StmtKind::Let(mut local) => smallvec![StmtKind::Let({
1372 vis.visit_local(&mut local);
1373 local
1374 })],
1375 StmtKind::Item(item) => vis.flat_map_item(item).into_iter().map(StmtKind::Item).collect(),
1376 StmtKind::Expr(expr) => vis.filter_map_expr(expr).into_iter().map(StmtKind::Expr).collect(),
1377 StmtKind::Semi(expr) => vis.filter_map_expr(expr).into_iter().map(StmtKind::Semi).collect(),
1378 StmtKind::Empty => smallvec![StmtKind::Empty],
1379 StmtKind::MacCall(mut mac) => {
1380 let MacCallStmt { mac: mac_, style: _, attrs, tokens: _ } = mac.deref_mut();
1381 visit_attrs(vis, attrs);
1382 vis.visit_mac_call(mac_);
1383 smallvec![StmtKind::MacCall(mac)]
1384 }
1385 }
1386}
1387
1388fn walk_vis<T: MutVisitor>(vis: &mut T, visibility: &mut Visibility) {
1389 let Visibility { kind, span, tokens: _ } = visibility;
1390 match kind {
1391 VisibilityKind::Public | VisibilityKind::Inherited => {}
1392 VisibilityKind::Restricted { path, id, shorthand: _ } => {
1393 vis.visit_id(id);
1394 vis.visit_path(path);
1395 }
1396 }
1397 vis.visit_span(span);
1398}
1399
1400fn walk_capture_by<T: MutVisitor>(vis: &mut T, capture_by: &mut CaptureBy) {
1401 match capture_by {
1402 CaptureBy::Ref => {}
1403 CaptureBy::Value { move_kw } => {
1404 vis.visit_span(move_kw);
1405 }
1406 CaptureBy::Use { use_kw } => {
1407 vis.visit_span(use_kw);
1408 }
1409 }
1410}
1411
1412#[derive(Debug)]
1413pub enum FnKind<'a> {
1414 Fn(FnCtxt, &'a mut Visibility, &'a mut Fn),
1416
1417 Closure(
1419 &'a mut ClosureBinder,
1420 &'a mut Option<CoroutineKind>,
1421 &'a mut P<FnDecl>,
1422 &'a mut P<Expr>,
1423 ),
1424}