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