1pub use rustc_ast_ir::visit::VisitorResult;
17pub use rustc_ast_ir::{try_visit, visit_opt, walk_list, walk_visitable_list};
18use rustc_span::{Ident, Span};
19use thin_vec::ThinVec;
20
21use crate::ast::*;
22use crate::ptr::P;
23
24#[derive(Copy, Clone, Debug, PartialEq)]
25pub enum AssocCtxt {
26 Trait,
27 Impl { of_trait: bool },
28}
29
30#[derive(Copy, Clone, Debug, PartialEq)]
31pub enum FnCtxt {
32 Free,
33 Foreign,
34 Assoc(AssocCtxt),
35}
36
37#[derive(Copy, Clone, Debug)]
38pub enum BoundKind {
39 Bound,
42
43 Impl,
46
47 TraitObject,
50
51 SuperTraits,
54}
55impl BoundKind {
56 pub fn descr(self) -> &'static str {
57 match self {
58 BoundKind::Bound => "bounds",
59 BoundKind::Impl => "`impl Trait`",
60 BoundKind::TraitObject => "`dyn` trait object bounds",
61 BoundKind::SuperTraits => "supertrait bounds",
62 }
63 }
64}
65
66#[derive(Copy, Clone, Debug)]
67pub enum FnKind<'a> {
68 Fn(FnCtxt, &'a Visibility, &'a Fn),
70
71 Closure(&'a ClosureBinder, &'a Option<CoroutineKind>, &'a FnDecl, &'a Expr),
73}
74
75impl<'a> FnKind<'a> {
76 pub fn header(&self) -> Option<&'a FnHeader> {
77 match *self {
78 FnKind::Fn(_, _, Fn { sig, .. }) => Some(&sig.header),
79 FnKind::Closure(..) => None,
80 }
81 }
82
83 pub fn ident(&self) -> Option<&Ident> {
84 match self {
85 FnKind::Fn(_, _, Fn { ident, .. }) => Some(ident),
86 _ => None,
87 }
88 }
89
90 pub fn decl(&self) -> &'a FnDecl {
91 match self {
92 FnKind::Fn(_, _, Fn { sig, .. }) => &sig.decl,
93 FnKind::Closure(_, _, decl, _) => decl,
94 }
95 }
96
97 pub fn ctxt(&self) -> Option<FnCtxt> {
98 match self {
99 FnKind::Fn(ctxt, ..) => Some(*ctxt),
100 FnKind::Closure(..) => None,
101 }
102 }
103}
104
105#[derive(Copy, Clone, Debug)]
106pub enum LifetimeCtxt {
107 Ref,
109 Bound,
111 GenericArg,
113}
114
115pub trait Visitor<'ast>: Sized {
129 type Result: VisitorResult = ();
132
133 fn visit_ident(&mut self, _ident: &'ast Ident) -> Self::Result {
134 Self::Result::output()
135 }
136 fn visit_foreign_mod(&mut self, nm: &'ast ForeignMod) -> Self::Result {
137 walk_foreign_mod(self, nm)
138 }
139 fn visit_foreign_item(&mut self, i: &'ast ForeignItem) -> Self::Result {
140 walk_item(self, i)
141 }
142 fn visit_item(&mut self, i: &'ast Item) -> Self::Result {
143 walk_item(self, i)
144 }
145 fn visit_local(&mut self, l: &'ast Local) -> Self::Result {
146 walk_local(self, l)
147 }
148 fn visit_block(&mut self, b: &'ast Block) -> Self::Result {
149 walk_block(self, b)
150 }
151 fn visit_stmt(&mut self, s: &'ast Stmt) -> Self::Result {
152 walk_stmt(self, s)
153 }
154 fn visit_param(&mut self, param: &'ast Param) -> Self::Result {
155 walk_param(self, param)
156 }
157 fn visit_arm(&mut self, a: &'ast Arm) -> Self::Result {
158 walk_arm(self, a)
159 }
160 fn visit_pat(&mut self, p: &'ast Pat) -> Self::Result {
161 walk_pat(self, p)
162 }
163 fn visit_anon_const(&mut self, c: &'ast AnonConst) -> Self::Result {
164 walk_anon_const(self, c)
165 }
166 fn visit_expr(&mut self, ex: &'ast Expr) -> Self::Result {
167 walk_expr(self, ex)
168 }
169 fn visit_method_receiver_expr(&mut self, ex: &'ast Expr) -> Self::Result {
172 self.visit_expr(ex)
173 }
174 fn visit_ty(&mut self, t: &'ast Ty) -> Self::Result {
175 walk_ty(self, t)
176 }
177 fn visit_ty_pat(&mut self, t: &'ast TyPat) -> Self::Result {
178 walk_ty_pat(self, t)
179 }
180 fn visit_generic_param(&mut self, param: &'ast GenericParam) -> Self::Result {
181 walk_generic_param(self, param)
182 }
183 fn visit_generics(&mut self, g: &'ast Generics) -> Self::Result {
184 walk_generics(self, g)
185 }
186 fn visit_closure_binder(&mut self, b: &'ast ClosureBinder) -> Self::Result {
187 walk_closure_binder(self, b)
188 }
189 fn visit_contract(&mut self, c: &'ast FnContract) -> Self::Result {
190 walk_contract(self, c)
191 }
192 fn visit_where_predicate(&mut self, p: &'ast WherePredicate) -> Self::Result {
193 walk_where_predicate(self, p)
194 }
195 fn visit_where_predicate_kind(&mut self, k: &'ast WherePredicateKind) -> Self::Result {
196 walk_where_predicate_kind(self, k)
197 }
198 fn visit_fn(&mut self, fk: FnKind<'ast>, _: Span, _: NodeId) -> Self::Result {
199 walk_fn(self, fk)
200 }
201 fn visit_assoc_item(&mut self, i: &'ast AssocItem, ctxt: AssocCtxt) -> Self::Result {
202 walk_assoc_item(self, i, ctxt)
203 }
204 fn visit_trait_ref(&mut self, t: &'ast TraitRef) -> Self::Result {
205 walk_trait_ref(self, t)
206 }
207 fn visit_param_bound(&mut self, bounds: &'ast GenericBound, _ctxt: BoundKind) -> Self::Result {
208 walk_param_bound(self, bounds)
209 }
210 fn visit_precise_capturing_arg(&mut self, arg: &'ast PreciseCapturingArg) -> Self::Result {
211 walk_precise_capturing_arg(self, arg)
212 }
213 fn visit_poly_trait_ref(&mut self, t: &'ast PolyTraitRef) -> Self::Result {
214 walk_poly_trait_ref(self, t)
215 }
216 fn visit_variant_data(&mut self, s: &'ast VariantData) -> Self::Result {
217 walk_variant_data(self, s)
218 }
219 fn visit_field_def(&mut self, s: &'ast FieldDef) -> Self::Result {
220 walk_field_def(self, s)
221 }
222 fn visit_enum_def(&mut self, enum_definition: &'ast EnumDef) -> Self::Result {
223 walk_enum_def(self, enum_definition)
224 }
225 fn visit_variant(&mut self, v: &'ast Variant) -> Self::Result {
226 walk_variant(self, v)
227 }
228 fn visit_variant_discr(&mut self, discr: &'ast AnonConst) -> Self::Result {
229 self.visit_anon_const(discr)
230 }
231 fn visit_label(&mut self, label: &'ast Label) -> Self::Result {
232 walk_label(self, label)
233 }
234 fn visit_lifetime(&mut self, lifetime: &'ast Lifetime, _: LifetimeCtxt) -> Self::Result {
235 walk_lifetime(self, lifetime)
236 }
237 fn visit_mac_call(&mut self, mac: &'ast MacCall) -> Self::Result {
238 walk_mac(self, mac)
239 }
240 fn visit_id(&mut self, _id: NodeId) -> Self::Result {
241 Self::Result::output()
242 }
243 fn visit_macro_def(&mut self, _mac: &'ast MacroDef) -> Self::Result {
244 Self::Result::output()
245 }
246 fn visit_path(&mut self, path: &'ast Path) -> Self::Result {
247 walk_path(self, path)
248 }
249 fn visit_use_tree(
250 &mut self,
251 use_tree: &'ast UseTree,
252 id: NodeId,
253 _nested: bool,
254 ) -> Self::Result {
255 walk_use_tree(self, use_tree, id)
256 }
257 fn visit_path_segment(&mut self, path_segment: &'ast PathSegment) -> Self::Result {
258 walk_path_segment(self, path_segment)
259 }
260 fn visit_generic_args(&mut self, generic_args: &'ast GenericArgs) -> Self::Result {
261 walk_generic_args(self, generic_args)
262 }
263 fn visit_generic_arg(&mut self, generic_arg: &'ast GenericArg) -> Self::Result {
264 walk_generic_arg(self, generic_arg)
265 }
266 fn visit_assoc_item_constraint(
267 &mut self,
268 constraint: &'ast AssocItemConstraint,
269 ) -> Self::Result {
270 walk_assoc_item_constraint(self, constraint)
271 }
272 fn visit_attribute(&mut self, attr: &'ast Attribute) -> Self::Result {
273 walk_attribute(self, attr)
274 }
275 fn visit_vis(&mut self, vis: &'ast Visibility) -> Self::Result {
276 walk_vis(self, vis)
277 }
278 fn visit_fn_ret_ty(&mut self, ret_ty: &'ast FnRetTy) -> Self::Result {
279 walk_fn_ret_ty(self, ret_ty)
280 }
281 fn visit_fn_header(&mut self, header: &'ast FnHeader) -> Self::Result {
282 walk_fn_header(self, header)
283 }
284 fn visit_expr_field(&mut self, f: &'ast ExprField) -> Self::Result {
285 walk_expr_field(self, f)
286 }
287 fn visit_pat_field(&mut self, fp: &'ast PatField) -> Self::Result {
288 walk_pat_field(self, fp)
289 }
290 fn visit_crate(&mut self, krate: &'ast Crate) -> Self::Result {
291 walk_crate(self, krate)
292 }
293 fn visit_inline_asm(&mut self, asm: &'ast InlineAsm) -> Self::Result {
294 walk_inline_asm(self, asm)
295 }
296 fn visit_format_args(&mut self, fmt: &'ast FormatArgs) -> Self::Result {
297 walk_format_args(self, fmt)
298 }
299 fn visit_inline_asm_sym(&mut self, sym: &'ast InlineAsmSym) -> Self::Result {
300 walk_inline_asm_sym(self, sym)
301 }
302 fn visit_capture_by(&mut self, _capture_by: &'ast CaptureBy) -> Self::Result {
303 Self::Result::output()
304 }
305 fn visit_coroutine_kind(&mut self, coroutine_kind: &'ast CoroutineKind) -> Self::Result {
306 walk_coroutine_kind(self, coroutine_kind)
307 }
308 fn visit_fn_decl(&mut self, fn_decl: &'ast FnDecl) -> Self::Result {
309 walk_fn_decl(self, fn_decl)
310 }
311 fn visit_qself(&mut self, qs: &'ast Option<P<QSelf>>) -> Self::Result {
312 walk_qself(self, qs)
313 }
314}
315
316#[macro_export]
317macro_rules! common_visitor_and_walkers {
318 ($(($mut: ident))? $Visitor:ident$(<$lt:lifetime>)?) => {
319 pub trait WalkItemKind {
320 type Ctxt;
321 fn walk<$($lt,)? V: $Visitor$(<$lt>)?>(
322 &$($lt)? $($mut)? self,
323 span: Span,
324 id: NodeId,
325 visibility: &$($lt)? $($mut)? Visibility,
326 ctxt: Self::Ctxt,
327 visitor: &mut V,
328 ) $(-> <V as Visitor<$lt>>::Result)?;
329 }
330
331 $(${ignore($lt)}
333 #[expect(unused, rustc::pass_by_value)]
334 #[inline]
335 )?
336 fn visit_span<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, span: &$($lt)? $($mut)? Span) $(-> <V as Visitor<$lt>>::Result)? {
337 $(
338 ${ignore($mut)}
339 visitor.visit_span(span);
340 )?
341 $(${ignore($lt)}V::Result::output())?
342 }
343
344 $(${ignore($lt)}
346 #[expect(rustc::pass_by_value)]
347 )?
348 #[inline]
349 fn visit_id<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, id: &$($lt)? $($mut)? NodeId) $(-> <V as Visitor<$lt>>::Result)? {
350 visitor.visit_id( $(${ignore($lt)} * )? id)
352 }
353
354 fn visit_safety<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, safety: &$($lt)? $($mut)? Safety) $(-> <V as Visitor<$lt>>::Result)? {
356 match safety {
357 Safety::Unsafe(span) => visit_span(vis, span),
358 Safety::Safe(span) => visit_span(vis, span),
359 Safety::Default => { $(${ignore($lt)}V::Result::output())? }
360 }
361 }
362
363 fn visit_constness<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, constness: &$($lt)? $($mut)? Const) $(-> <V as Visitor<$lt>>::Result)? {
364 match constness {
365 Const::Yes(span) => visit_span(vis, span),
366 Const::No => {
367 $(<V as Visitor<$lt>>::Result::output())?
368 }
369 }
370 }
371
372 fn visit_defaultness<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, defaultness: &$($lt)? $($mut)? Defaultness) $(-> <V as Visitor<$lt>>::Result)? {
373 match defaultness {
374 Defaultness::Default(span) => visit_span(vis, span),
375 Defaultness::Final => {
376 $(<V as Visitor<$lt>>::Result::output())?
377 }
378 }
379 }
380
381 fn visit_polarity<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, polarity: &$($lt)? $($mut)? ImplPolarity) $(-> <V as Visitor<$lt>>::Result)? {
382 match polarity {
383 ImplPolarity::Positive => { $(<V as Visitor<$lt>>::Result::output())? }
384 ImplPolarity::Negative(span) => visit_span(vis, span),
385 }
386 }
387
388 fn visit_bounds<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, bounds: &$($lt)? $($mut)? GenericBounds, ctxt: BoundKind) $(-> <V as Visitor<$lt>>::Result)? {
389 walk_list!(visitor, visit_param_bound, bounds, ctxt);
390 $(<V as Visitor<$lt>>::Result::output())?
391 }
392
393 pub fn walk_label<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, Label { ident }: &$($lt)? $($mut)? Label) $(-> <V as Visitor<$lt>>::Result)? {
394 visitor.visit_ident(ident)
395 }
396
397 pub fn walk_fn_header<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, header: &$($lt)? $($mut)? FnHeader) $(-> <V as Visitor<$lt>>::Result)? {
398 let FnHeader { safety, coroutine_kind, constness, ext: _ } = header;
399 try_visit!(visit_constness(visitor, constness));
400 visit_opt!(visitor, visit_coroutine_kind, coroutine_kind);
401 visit_safety(visitor, safety)
402 }
403
404 pub fn walk_lifetime<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, Lifetime { id, ident }: &$($lt)? $($mut)? Lifetime) $(-> <V as Visitor<$lt>>::Result)? {
405 try_visit!(visit_id(visitor, id));
406 visitor.visit_ident(ident)
407 }
408
409 fn walk_item_ctxt<$($lt,)? V: $Visitor$(<$lt>)?, K: WalkItemKind>(
410 visitor: &mut V,
411 item: &$($mut)? $($lt)? Item<K>,
412 ctxt: K::Ctxt,
413 ) $(-> <V as Visitor<$lt>>::Result)? {
414 let Item { attrs, id, kind, vis, span, tokens: _ } = item;
415 try_visit!(visit_id(visitor, id));
416 walk_list!(visitor, visit_attribute, attrs);
417 try_visit!(visitor.visit_vis(vis));
418 try_visit!(kind.walk(*span, *id, vis, ctxt, visitor));
419 visit_span(visitor, span)
420 }
421
422 pub fn walk_item<$($lt,)? V: $Visitor$(<$lt>)?, K: WalkItemKind<Ctxt = ()>>(
423 visitor: &mut V,
424 item: &$($mut)? $($lt)? Item<K>,
425 ) $(-> <V as Visitor<$lt>>::Result)? {
426 walk_item_ctxt(visitor, item, ())
427 }
428
429 pub fn walk_assoc_item<$($lt,)? V: $Visitor$(<$lt>)?>(
430 visitor: &mut V,
431 item: &$($mut)? $($lt)? AssocItem,
432 ctxt: AssocCtxt,
433 ) $(-> <V as Visitor<$lt>>::Result)? {
434 walk_item_ctxt(visitor, item, ctxt)
435 }
436
437 impl WalkItemKind for ItemKind {
438 type Ctxt = ();
439 fn walk<$($lt,)? V: $Visitor$(<$lt>)?>(
440 &$($lt)? $($mut)? self,
441 span: Span,
442 id: NodeId,
443 visibility: &$($lt)? $($mut)? Visibility,
444 _ctxt: Self::Ctxt,
445 vis: &mut V,
446 ) $(-> <V as Visitor<$lt>>::Result)? {
447 match self {
448 ItemKind::ExternCrate(_orig_name, ident) => vis.visit_ident(ident),
449 ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree$(${ignore($lt)}, id, false)?),
451 ItemKind::Static(box StaticItem {
452 ident,
453 ty,
454 safety: _,
455 mutability: _,
456 expr,
457 define_opaque,
458 }) => {
459 try_visit!(vis.visit_ident(ident));
460 try_visit!(vis.visit_ty(ty));
461 visit_opt!(vis, visit_expr, expr);
462 walk_define_opaques(vis, define_opaque)
463 }
464 ItemKind::Const(item) => {
465 walk_const_item(vis, item)
466 }
467 ItemKind::Fn(func) => {
468 let kind = FnKind::Fn(FnCtxt::Free, visibility, &$($mut)? *func);
469 vis.visit_fn(kind, span, id)
470 }
471 ItemKind::Mod(safety, ident, mod_kind) => {
472 try_visit!(visit_safety(vis, safety));
473 try_visit!(vis.visit_ident(ident));
474 match mod_kind {
475 ModKind::Loaded(
476 items,
477 _inline,
478 ModSpans { inner_span, inject_use_span },
479 _,
480 ) => {
481 $(${ignore($mut)}
482 items.flat_map_in_place(|item| vis.flat_map_item(item));
483 )?
484 $(${ignore($lt)}
485 walk_list!(vis, visit_item, items);
486 )?
487 try_visit!(visit_span(vis, inner_span));
488 try_visit!(visit_span(vis, inject_use_span));
489 }
490 ModKind::Unloaded => {}
491 }
492 $(<V as Visitor<$lt>>::Result::output())?
493 }
494 ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
495 ItemKind::GlobalAsm(asm) => vis.visit_inline_asm(asm),
496 ItemKind::TyAlias(box TyAlias {
497 defaultness,
498 ident,
499 generics,
500 $(${ignore($lt)} #[expect(unused)])?
501 where_clauses,
502 bounds,
503 ty,
504 }) => {
505 try_visit!(visit_defaultness(vis, defaultness));
506 try_visit!(vis.visit_ident(ident));
507 try_visit!(vis.visit_generics(generics));
508 try_visit!(visit_bounds(vis, bounds, BoundKind::Bound));
509 visit_opt!(vis, visit_ty, ty);
510 $(${ignore($mut)}
511 walk_ty_alias_where_clauses(vis, where_clauses);
512 )?
513 $(<V as Visitor<$lt>>::Result::output())?
514 }
515 ItemKind::Enum(ident, generics, enum_definition) => {
516 try_visit!(vis.visit_ident(ident));
517 try_visit!(vis.visit_generics(generics));
518 $(${ignore($mut)}
519 enum_definition.variants.flat_map_in_place(|variant| vis.flat_map_variant(variant));
520 )?
521 $(${ignore($lt)}vis.visit_enum_def(enum_definition))?
522 }
523 ItemKind::Struct(ident, generics, variant_data)
524 | ItemKind::Union(ident, generics, variant_data) => {
525 try_visit!(vis.visit_ident(ident));
526 try_visit!(vis.visit_generics(generics));
527 vis.visit_variant_data(variant_data)
528 }
529 ItemKind::Impl(box Impl {
530 defaultness,
531 safety,
532 generics,
533 constness,
534 polarity,
535 of_trait,
536 self_ty,
537 items,
538 }) => {
539 try_visit!(visit_defaultness(vis, defaultness));
540 try_visit!(visit_safety(vis, safety));
541 try_visit!(vis.visit_generics(generics));
542 try_visit!(visit_constness(vis, constness));
543 try_visit!(visit_polarity(vis, polarity));
544 visit_opt!(vis, visit_trait_ref, of_trait);
545 try_visit!(vis.visit_ty(self_ty));
546 $(${ignore($mut)}
547 items.flat_map_in_place(|item| {
548 vis.flat_map_assoc_item(item, AssocCtxt::Impl { of_trait: of_trait.is_some() })
549 });
550 )?
551 $(${ignore($lt)}
552 walk_list!(
553 vis,
554 visit_assoc_item,
555 items,
556 AssocCtxt::Impl { of_trait: of_trait.is_some() }
557 );
558 <V as Visitor<$lt>>::Result::output()
559 )?
560 }
561 ItemKind::Trait(box Trait { safety, is_auto: _, ident, generics, bounds, items }) => {
562 try_visit!(visit_safety(vis, safety));
563 try_visit!(vis.visit_ident(ident));
564 try_visit!(vis.visit_generics(generics));
565 try_visit!(visit_bounds(vis, bounds, BoundKind::Bound));
566 $(${ignore($mut)}
567 items.flat_map_in_place(|item| {
568 vis.flat_map_assoc_item(item, AssocCtxt::Trait)
569 });
570 )?
571 $(${ignore($lt)}
572 walk_list!(vis, visit_assoc_item, items, AssocCtxt::Trait);
573 <V as Visitor<$lt>>::Result::output()
574 )?
575 }
576 ItemKind::TraitAlias(ident, generics, bounds) => {
577 try_visit!(vis.visit_ident(ident));
578 try_visit!(vis.visit_generics(generics));
579 visit_bounds(vis, bounds, BoundKind::Bound)
580 }
581 ItemKind::MacCall(m) => vis.visit_mac_call(m),
582 ItemKind::MacroDef(ident, def) => {
583 try_visit!(vis.visit_ident(ident));
584 vis.visit_macro_def(def)
585 }
586 ItemKind::Delegation(box Delegation {
587 id,
588 qself,
589 path,
590 ident,
591 rename,
592 body,
593 from_glob: _,
594 }) => {
595 try_visit!(visit_id(vis, id));
596 try_visit!(vis.visit_qself(qself));
597 try_visit!(vis.visit_path(path));
598 try_visit!(vis.visit_ident(ident));
599 visit_opt!(vis, visit_ident, rename);
600 visit_opt!(vis, visit_block, body);
601 $(<V as Visitor<$lt>>::Result::output())?
602 }
603 ItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => {
604 try_visit!(vis.visit_qself(qself));
605 try_visit!(vis.visit_path(prefix));
606 if let Some(suffixes) = suffixes {
607 for (ident, rename) in suffixes {
608 try_visit!(vis.visit_ident(ident));
609 visit_opt!(vis, visit_ident, rename);
610 }
611 }
612 visit_opt!(vis, visit_block, body);
613 $(<V as Visitor<$lt>>::Result::output())?
614 }
615 }
616 }
617 }
618
619 fn walk_const_item<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, item: &$($lt)? $($mut)? ConstItem) $(-> <V as Visitor<$lt>>::Result)? {
620 let ConstItem { defaultness, ident, generics, ty, expr, define_opaque } = item;
621 try_visit!(visit_defaultness(vis, defaultness));
622 try_visit!(vis.visit_ident(ident));
623 try_visit!(vis.visit_generics(generics));
624 try_visit!(vis.visit_ty(ty));
625 visit_opt!(vis, visit_expr, expr);
626 walk_define_opaques(vis, define_opaque)
627 }
628
629 fn walk_foreign_mod<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, foreign_mod: &$($lt)? $($mut)? ForeignMod) $(-> <V as Visitor<$lt>>::Result)? {
630 let ForeignMod { extern_span: _, safety, abi: _, items } = foreign_mod;
631 try_visit!(visit_safety(vis, safety));
632 $(${ignore($mut)}
633 items.flat_map_in_place(|item| vis.flat_map_foreign_item(item));
634 )?
635 $(
636 walk_list!(vis, visit_foreign_item, items);
637 <V as Visitor<$lt>>::Result::output()
638 )?
639 }
640
641 fn walk_define_opaques<$($lt,)? V: $Visitor$(<$lt>)?>(
642 visitor: &mut V,
643 define_opaque: &$($lt)? $($mut)? Option<ThinVec<(NodeId, Path)>>,
644 ) $(-> <V as Visitor<$lt>>::Result)? {
645 if let Some(define_opaque) = define_opaque {
646 for (id, path) in define_opaque {
647 try_visit!(visit_id(visitor, id));
648 try_visit!(visitor.visit_path(path));
649 }
650 }
651 $(<V as Visitor<$lt>>::Result::output())?
652 }
653
654 impl WalkItemKind for AssocItemKind {
655 type Ctxt = AssocCtxt;
656 fn walk<$($lt,)? V: $Visitor$(<$lt>)?>(
657 &$($lt)? $($mut)? self,
658 span: Span,
659 id: NodeId,
660 visibility: &$($lt)? $($mut)? Visibility,
661 ctxt: Self::Ctxt,
662 vis: &mut V,
663 ) $(-> <V as Visitor<$lt>>::Result)? {
664 match self {
665 AssocItemKind::Const(item) => {
666 walk_const_item(vis, item)
667 }
668 AssocItemKind::Fn(func) => {
669 vis.visit_fn(FnKind::Fn(FnCtxt::Assoc(ctxt), visibility, &$($mut)? *func), span, id)
670 }
671 AssocItemKind::Type(box TyAlias {
672 generics,
673 ident,
674 bounds,
675 ty,
676 defaultness,
677 $(${ignore($lt)} #[expect(unused)])?
678 where_clauses,
679 }) => {
680 try_visit!(visit_defaultness(vis, defaultness));
681 try_visit!(vis.visit_ident(ident));
682 try_visit!(vis.visit_generics(generics));
683 try_visit!(visit_bounds(vis, bounds, BoundKind::Bound));
684 visit_opt!(vis, visit_ty, ty);
685 $(${ignore($mut)}
686 walk_ty_alias_where_clauses(vis, where_clauses);
687 )?
688 $(<V as Visitor<$lt>>::Result::output())?
689 }
690 AssocItemKind::MacCall(mac) => {
691 vis.visit_mac_call(mac)
692 }
693 AssocItemKind::Delegation(box Delegation {
694 id,
695 qself,
696 path,
697 ident,
698 rename,
699 body,
700 from_glob: _,
701 }) => {
702 try_visit!(visit_id(vis, id));
703 try_visit!(vis.visit_qself(qself));
704 try_visit!(vis.visit_path(path));
705 try_visit!(vis.visit_ident(ident));
706 visit_opt!(vis, visit_ident, rename);
707 visit_opt!(vis, visit_block, body);
708 $(<V as Visitor<$lt>>::Result::output())?
709 }
710 AssocItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => {
711 try_visit!(vis.visit_qself(qself));
712 try_visit!(vis.visit_path(prefix));
713 if let Some(suffixes) = suffixes {
714 for (ident, rename) in suffixes {
715 try_visit!(vis.visit_ident(ident));
716 visit_opt!(vis, visit_ident, rename);
717 }
718 }
719 visit_opt!(vis, visit_block, body);
720 $(<V as Visitor<$lt>>::Result::output())?
721 }
722 }
723 }
724 }
725
726 impl WalkItemKind for ForeignItemKind {
727 type Ctxt = ();
728 fn walk<$($lt,)? V: $Visitor$(<$lt>)?>(
729 &$($lt)? $($mut)? self,
730 span: Span,
731 id: NodeId,
732 visibility: &$($lt)? $($mut)? Visibility,
733 _ctxt: Self::Ctxt,
734 vis: &mut V,
735 ) $(-> <V as Visitor<$lt>>::Result)? {
736 match self {
737 ForeignItemKind::Static(box StaticItem {
738 ident,
739 ty,
740 mutability: _,
741 expr,
742 safety: _,
743 define_opaque,
744 }) => {
745 try_visit!(vis.visit_ident(ident));
746 try_visit!(vis.visit_ty(ty));
747 visit_opt!(vis, visit_expr, expr);
748 walk_define_opaques(vis, define_opaque)
749 }
750 ForeignItemKind::Fn(func) => {
751 vis.visit_fn(FnKind::Fn(FnCtxt::Foreign, visibility, &$($mut)?*func), span, id)
752 }
753 ForeignItemKind::TyAlias(box TyAlias {
754 defaultness,
755 ident,
756 generics,
757 bounds,
758 ty,
759 $(${ignore($lt)} #[expect(unused)])?
760 where_clauses,
761 }) => {
762 try_visit!(visit_defaultness(vis, defaultness));
763 try_visit!(vis.visit_ident(ident));
764 try_visit!(vis.visit_generics(generics));
765 try_visit!(visit_bounds(vis, bounds, BoundKind::Bound));
766 visit_opt!(vis, visit_ty, ty);
767 $(${ignore($mut)}
768 walk_ty_alias_where_clauses(vis, where_clauses);
769 )?
770 $(<V as Visitor<$lt>>::Result::output())?
771 }
772 ForeignItemKind::MacCall(mac) => {
773 vis.visit_mac_call(mac)
774 }
775 }
776 }
777 }
778
779 fn walk_coroutine_kind<$($lt,)? V: $Visitor$(<$lt>)?>(
780 vis: &mut V,
781 coroutine_kind: &$($lt)? $($mut)? CoroutineKind,
782 ) $(-> <V as Visitor<$lt>>::Result)? {
783 match coroutine_kind {
784 CoroutineKind::Async { span, closure_id, return_impl_trait_id }
785 | CoroutineKind::Gen { span, closure_id, return_impl_trait_id }
786 | CoroutineKind::AsyncGen { span, closure_id, return_impl_trait_id } => {
787 try_visit!(visit_id(vis, closure_id));
788 try_visit!(visit_id(vis, return_impl_trait_id));
789 visit_span(vis, span)
790 }
791 }
792 }
793
794 pub fn walk_pat<$($lt,)? V: $Visitor$(<$lt>)?>(
795 vis: &mut V,
796 pattern: &$($lt)? $($mut)? Pat
797 ) $(-> <V as Visitor<$lt>>::Result)? {
798 let Pat { id, kind, span, tokens: _ } = pattern;
799 try_visit!(visit_id(vis, id));
800 match kind {
801 PatKind::Err(_guar) => {}
802 PatKind::Missing | PatKind::Wild | PatKind::Rest | PatKind::Never => {}
803 PatKind::Ident(_bmode, ident, optional_subpattern) => {
804 try_visit!(vis.visit_ident(ident));
805 visit_opt!(vis, visit_pat, optional_subpattern);
806 }
807 PatKind::Expr(expression) => try_visit!(vis.visit_expr(expression)),
808 PatKind::TupleStruct(opt_qself, path, elems) => {
809 try_visit!(vis.visit_qself(opt_qself));
810 try_visit!(vis.visit_path(path));
811 walk_list!(vis, visit_pat, elems);
812 }
813 PatKind::Path(opt_qself, path) => {
814 try_visit!(vis.visit_qself(opt_qself));
815 try_visit!(vis.visit_path(path))
816 }
817 PatKind::Struct(opt_qself, path, fields, _rest) => {
818 try_visit!(vis.visit_qself(opt_qself));
819 try_visit!(vis.visit_path(path));
820
821 $(
822 ${ignore($lt)}
823 walk_list!(vis, visit_pat_field, fields);
824 )?
825 $(
826 ${ignore($mut)}
827 fields.flat_map_in_place(|field| vis.flat_map_pat_field(field));
828 )?
829 }
830 PatKind::Box(subpattern) | PatKind::Deref(subpattern) | PatKind::Paren(subpattern) => {
831 try_visit!(vis.visit_pat(subpattern));
832 }
833 PatKind::Ref(subpattern, _ ) => {
834 try_visit!(vis.visit_pat(subpattern));
835 }
836 PatKind::Range(lower_bound, upper_bound, _end) => {
837 visit_opt!(vis, visit_expr, lower_bound);
838 visit_opt!(vis, visit_expr, upper_bound);
839 try_visit!(visit_span(vis, span));
840 }
841 PatKind::Guard(subpattern, guard_condition) => {
842 try_visit!(vis.visit_pat(subpattern));
843 try_visit!(vis.visit_expr(guard_condition));
844 }
845 PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => {
846 walk_list!(vis, visit_pat, elems);
847 }
848 PatKind::MacCall(mac) => try_visit!(vis.visit_mac_call(mac)),
849 }
850 visit_span(vis, span)
851 }
852
853 pub fn walk_anon_const<$($lt,)? V: $Visitor$(<$lt>)?>(
854 vis: &mut V,
855 constant: &$($lt)? $($mut)? AnonConst,
856 ) $(-> <V as Visitor<$lt>>::Result)? {
857 let AnonConst { id, value } = constant;
858 try_visit!(visit_id(vis, id));
859 vis.visit_expr(value)
860 }
861
862 pub fn walk_path_segment<$($lt,)? V: $Visitor$(<$lt>)?>(
863 vis: &mut V,
864 segment: &$($lt)? $($mut)? PathSegment,
865 ) $(-> <V as Visitor<$lt>>::Result)? {
866 let PathSegment { ident, id, args } = segment;
867 try_visit!(visit_id(vis, id));
868 try_visit!(vis.visit_ident(ident));
869 visit_opt!(vis, visit_generic_args, args);
870 $(<V as Visitor<$lt>>::Result::output())?
871 }
872
873 pub fn walk_block<$($lt,)? V: $Visitor$(<$lt>)?>(
874 vis: &mut V,
875 block: &$($lt)? $($mut)? Block
876 ) $(-> <V as Visitor<$lt>>::Result)? {
877 let Block { stmts, id, rules: _, span, tokens: _ } = block;
878 try_visit!(visit_id(vis, id));
879 $(
880 ${ignore($lt)}
881 walk_list!(vis, visit_stmt, stmts);
882 )?
883 $(
884 ${ignore($mut)}
885 stmts.flat_map_in_place(|stmt| vis.flat_map_stmt(stmt));
886 )?
887 visit_span(vis, span)
888 }
889
890
891 pub fn walk_ty<$($lt,)? V: $Visitor$(<$lt>)?>(
892 vis: &mut V, ty: &$($lt)? $($mut)? Ty
893 ) $(-> <V as Visitor<$lt>>::Result)? {
894 let Ty { id, kind, span, tokens: _ } = ty;
895 try_visit!(visit_id(vis, id));
896 match kind {
897 TyKind::Err(_guar) => {}
898 TyKind::Infer | TyKind::ImplicitSelf | TyKind::Dummy | TyKind::Never | TyKind::CVarArgs => {}
899 TyKind::Slice(ty) | TyKind::Paren(ty) => try_visit!(vis.visit_ty(ty)),
900 TyKind::Ptr(MutTy { ty, mutbl: _ }) => try_visit!(vis.visit_ty(ty)),
901 TyKind::Ref(opt_lifetime, MutTy { ty, mutbl: _ })
902 | TyKind::PinnedRef(opt_lifetime, MutTy { ty, mutbl: _ }) => {
903 visit_opt!(vis, visit_lifetime, opt_lifetime$(${ignore($lt)}, LifetimeCtxt::Ref)?);
905 try_visit!(vis.visit_ty(ty));
906 }
907 TyKind::Tup(tuple_element_types) => {
908 walk_list!(vis, visit_ty, tuple_element_types);
909 }
910 TyKind::BareFn(function_declaration) => {
911 let BareFnTy { safety, ext: _, generic_params, decl, decl_span } =
912 &$($mut)? **function_declaration;
913 visit_safety(vis, safety);
914 $(
915 ${ignore($lt)}
916 walk_list!(vis, visit_generic_param, generic_params);
917 )?
918 $(
919 ${ignore($mut)}
920 generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
921 )?
922
923 try_visit!(vis.visit_fn_decl(decl));
924 try_visit!(visit_span(vis, decl_span));
925 }
926 TyKind::UnsafeBinder(binder) => {
927 $(
928 ${ignore($lt)}
929 walk_list!(vis, visit_generic_param, &binder.generic_params);
930 )?
931 $(
932 ${ignore($mut)}
933 binder.generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
934 )?
935 try_visit!(vis.visit_ty(&$($mut)?binder.inner_ty));
936 }
937 TyKind::Path(maybe_qself, path) => {
938 try_visit!(vis.visit_qself(maybe_qself));
939 try_visit!(vis.visit_path(path));
940 }
941 TyKind::Pat(ty, pat) => {
942 try_visit!(vis.visit_ty(ty));
943 try_visit!(vis.visit_ty_pat(pat));
944 }
945 TyKind::Array(ty, length) => {
946 try_visit!(vis.visit_ty(ty));
947 try_visit!(vis.visit_anon_const(length));
948 }
949 TyKind::TraitObject(bounds, _syntax) => {
950 walk_list!(vis, visit_param_bound, bounds, BoundKind::TraitObject);
951 }
952 TyKind::ImplTrait(id, bounds) => {
953 try_visit!(visit_id(vis, id));
954 walk_list!(vis, visit_param_bound, bounds, BoundKind::Impl);
955 }
956 TyKind::Typeof(expression) => try_visit!(vis.visit_anon_const(expression)),
957
958 TyKind::MacCall(mac) => try_visit!(vis.visit_mac_call(mac)),
959 }
960 visit_span(vis, span)
961 }
962 };
963}
964
965common_visitor_and_walkers!(Visitor<'a>);
966
967pub fn walk_crate<'a, V: Visitor<'a>>(visitor: &mut V, krate: &'a Crate) -> V::Result {
968 let Crate { attrs, items, spans: _, id: _, is_placeholder: _ } = krate;
969 walk_list!(visitor, visit_attribute, attrs);
970 walk_list!(visitor, visit_item, items);
971 V::Result::output()
972}
973
974pub fn walk_local<'a, V: Visitor<'a>>(visitor: &mut V, local: &'a Local) -> V::Result {
975 let Local { id: _, super_: _, pat, ty, kind, span: _, colon_sp: _, attrs, tokens: _ } = local;
976 walk_list!(visitor, visit_attribute, attrs);
977 try_visit!(visitor.visit_pat(pat));
978 visit_opt!(visitor, visit_ty, ty);
979 if let Some((init, els)) = kind.init_else_opt() {
980 try_visit!(visitor.visit_expr(init));
981 visit_opt!(visitor, visit_block, els);
982 }
983 V::Result::output()
984}
985
986pub fn walk_poly_trait_ref<'a, V>(visitor: &mut V, trait_ref: &'a PolyTraitRef) -> V::Result
987where
988 V: Visitor<'a>,
989{
990 let PolyTraitRef { bound_generic_params, modifiers: _, trait_ref, span: _ } = trait_ref;
991 walk_list!(visitor, visit_generic_param, bound_generic_params);
992 visitor.visit_trait_ref(trait_ref)
993}
994
995pub fn walk_trait_ref<'a, V: Visitor<'a>>(visitor: &mut V, trait_ref: &'a TraitRef) -> V::Result {
996 let TraitRef { path, ref_id } = trait_ref;
997 try_visit!(visitor.visit_path(path));
998 visitor.visit_id(*ref_id)
999}
1000
1001pub fn walk_enum_def<'a, V: Visitor<'a>>(
1002 visitor: &mut V,
1003 EnumDef { variants }: &'a EnumDef,
1004) -> V::Result {
1005 walk_list!(visitor, visit_variant, variants);
1006 V::Result::output()
1007}
1008
1009pub fn walk_variant<'a, V: Visitor<'a>>(visitor: &mut V, variant: &'a Variant) -> V::Result
1010where
1011 V: Visitor<'a>,
1012{
1013 let Variant { attrs, id: _, span: _, vis, ident, data, disr_expr, is_placeholder: _ } = variant;
1014 walk_list!(visitor, visit_attribute, attrs);
1015 try_visit!(visitor.visit_vis(vis));
1016 try_visit!(visitor.visit_ident(ident));
1017 try_visit!(visitor.visit_variant_data(data));
1018 visit_opt!(visitor, visit_variant_discr, disr_expr);
1019 V::Result::output()
1020}
1021
1022pub fn walk_expr_field<'a, V: Visitor<'a>>(visitor: &mut V, f: &'a ExprField) -> V::Result {
1023 let ExprField { attrs, id: _, span: _, ident, expr, is_shorthand: _, is_placeholder: _ } = f;
1024 walk_list!(visitor, visit_attribute, attrs);
1025 try_visit!(visitor.visit_ident(ident));
1026 try_visit!(visitor.visit_expr(expr));
1027 V::Result::output()
1028}
1029
1030pub fn walk_pat_field<'a, V: Visitor<'a>>(visitor: &mut V, fp: &'a PatField) -> V::Result {
1031 let PatField { ident, pat, is_shorthand: _, attrs, id: _, span: _, is_placeholder: _ } = fp;
1032 walk_list!(visitor, visit_attribute, attrs);
1033 try_visit!(visitor.visit_ident(ident));
1034 try_visit!(visitor.visit_pat(pat));
1035 V::Result::output()
1036}
1037
1038pub fn walk_ty_pat<'a, V: Visitor<'a>>(visitor: &mut V, tp: &'a TyPat) -> V::Result {
1039 let TyPat { id: _, kind, span: _, tokens: _ } = tp;
1040 match kind {
1041 TyPatKind::Range(start, end, _include_end) => {
1042 visit_opt!(visitor, visit_anon_const, start);
1043 visit_opt!(visitor, visit_anon_const, end);
1044 }
1045 TyPatKind::Or(variants) => walk_list!(visitor, visit_ty_pat, variants),
1046 TyPatKind::Err(_) => {}
1047 }
1048 V::Result::output()
1049}
1050
1051fn walk_qself<'a, V: Visitor<'a>>(visitor: &mut V, qself: &'a Option<P<QSelf>>) -> V::Result {
1052 if let Some(qself) = qself {
1053 let QSelf { ty, path_span: _, position: _ } = &**qself;
1054 try_visit!(visitor.visit_ty(ty));
1055 }
1056 V::Result::output()
1057}
1058
1059pub fn walk_path<'a, V: Visitor<'a>>(visitor: &mut V, path: &'a Path) -> V::Result {
1060 let Path { span: _, segments, tokens: _ } = path;
1061 walk_list!(visitor, visit_path_segment, segments);
1062 V::Result::output()
1063}
1064
1065pub fn walk_use_tree<'a, V: Visitor<'a>>(
1066 visitor: &mut V,
1067 use_tree: &'a UseTree,
1068 id: NodeId,
1069) -> V::Result {
1070 let UseTree { prefix, kind, span: _ } = use_tree;
1071 try_visit!(visitor.visit_id(id));
1072 try_visit!(visitor.visit_path(prefix));
1073 match kind {
1074 UseTreeKind::Simple(rename) => {
1075 visit_opt!(visitor, visit_ident, rename);
1077 }
1078 UseTreeKind::Glob => {}
1079 UseTreeKind::Nested { items, span: _ } => {
1080 for &(ref nested_tree, nested_id) in items {
1081 try_visit!(visitor.visit_use_tree(nested_tree, nested_id, true));
1082 }
1083 }
1084 }
1085 V::Result::output()
1086}
1087
1088pub fn walk_generic_args<'a, V>(visitor: &mut V, generic_args: &'a GenericArgs) -> V::Result
1089where
1090 V: Visitor<'a>,
1091{
1092 match generic_args {
1093 GenericArgs::AngleBracketed(AngleBracketedArgs { span: _, args }) => {
1094 for arg in args {
1095 match arg {
1096 AngleBracketedArg::Arg(a) => try_visit!(visitor.visit_generic_arg(a)),
1097 AngleBracketedArg::Constraint(c) => {
1098 try_visit!(visitor.visit_assoc_item_constraint(c))
1099 }
1100 }
1101 }
1102 }
1103 GenericArgs::Parenthesized(data) => {
1104 let ParenthesizedArgs { span: _, inputs, inputs_span: _, output } = data;
1105 walk_list!(visitor, visit_ty, inputs);
1106 try_visit!(visitor.visit_fn_ret_ty(output));
1107 }
1108 GenericArgs::ParenthesizedElided(_span) => {}
1109 }
1110 V::Result::output()
1111}
1112
1113pub fn walk_generic_arg<'a, V>(visitor: &mut V, generic_arg: &'a GenericArg) -> V::Result
1114where
1115 V: Visitor<'a>,
1116{
1117 match generic_arg {
1118 GenericArg::Lifetime(lt) => visitor.visit_lifetime(lt, LifetimeCtxt::GenericArg),
1119 GenericArg::Type(ty) => visitor.visit_ty(ty),
1120 GenericArg::Const(ct) => visitor.visit_anon_const(ct),
1121 }
1122}
1123
1124pub fn walk_assoc_item_constraint<'a, V: Visitor<'a>>(
1125 visitor: &mut V,
1126 constraint: &'a AssocItemConstraint,
1127) -> V::Result {
1128 let AssocItemConstraint { id: _, ident, gen_args, kind, span: _ } = constraint;
1129 try_visit!(visitor.visit_ident(ident));
1130 visit_opt!(visitor, visit_generic_args, gen_args);
1131 match kind {
1132 AssocItemConstraintKind::Equality { term } => match term {
1133 Term::Ty(ty) => try_visit!(visitor.visit_ty(ty)),
1134 Term::Const(c) => try_visit!(visitor.visit_anon_const(c)),
1135 },
1136 AssocItemConstraintKind::Bound { bounds } => {
1137 walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
1138 }
1139 }
1140 V::Result::output()
1141}
1142
1143pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericBound) -> V::Result {
1144 match bound {
1145 GenericBound::Trait(trait_ref) => visitor.visit_poly_trait_ref(trait_ref),
1146 GenericBound::Outlives(lifetime) => visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound),
1147 GenericBound::Use(args, _span) => {
1148 walk_list!(visitor, visit_precise_capturing_arg, args);
1149 V::Result::output()
1150 }
1151 }
1152}
1153
1154pub fn walk_precise_capturing_arg<'a, V: Visitor<'a>>(
1155 visitor: &mut V,
1156 arg: &'a PreciseCapturingArg,
1157) -> V::Result {
1158 match arg {
1159 PreciseCapturingArg::Lifetime(lt) => visitor.visit_lifetime(lt, LifetimeCtxt::GenericArg),
1160 PreciseCapturingArg::Arg(path, id) => {
1161 try_visit!(visitor.visit_id(*id));
1162 visitor.visit_path(path)
1163 }
1164 }
1165}
1166
1167pub fn walk_generic_param<'a, V: Visitor<'a>>(
1168 visitor: &mut V,
1169 param: &'a GenericParam,
1170) -> V::Result {
1171 let GenericParam { id: _, ident, attrs, bounds, is_placeholder: _, kind, colon_span: _ } =
1172 param;
1173 walk_list!(visitor, visit_attribute, attrs);
1174 try_visit!(visitor.visit_ident(ident));
1175 walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
1176 match kind {
1177 GenericParamKind::Lifetime => (),
1178 GenericParamKind::Type { default } => visit_opt!(visitor, visit_ty, default),
1179 GenericParamKind::Const { ty, default, kw_span: _ } => {
1180 try_visit!(visitor.visit_ty(ty));
1181 visit_opt!(visitor, visit_anon_const, default);
1182 }
1183 }
1184 V::Result::output()
1185}
1186
1187pub fn walk_generics<'a, V: Visitor<'a>>(visitor: &mut V, generics: &'a Generics) -> V::Result {
1188 let Generics { params, where_clause, span: _ } = generics;
1189 let WhereClause { has_where_token: _, predicates, span: _ } = where_clause;
1190 walk_list!(visitor, visit_generic_param, params);
1191 walk_list!(visitor, visit_where_predicate, predicates);
1192 V::Result::output()
1193}
1194
1195pub fn walk_closure_binder<'a, V: Visitor<'a>>(
1196 visitor: &mut V,
1197 binder: &'a ClosureBinder,
1198) -> V::Result {
1199 match binder {
1200 ClosureBinder::NotPresent => {}
1201 ClosureBinder::For { generic_params, span: _ } => {
1202 walk_list!(visitor, visit_generic_param, generic_params)
1203 }
1204 }
1205 V::Result::output()
1206}
1207
1208pub fn walk_contract<'a, V: Visitor<'a>>(visitor: &mut V, c: &'a FnContract) -> V::Result {
1209 let FnContract { requires, ensures } = c;
1210 if let Some(pred) = requires {
1211 visitor.visit_expr(pred);
1212 }
1213 if let Some(pred) = ensures {
1214 visitor.visit_expr(pred);
1215 }
1216 V::Result::output()
1217}
1218
1219pub fn walk_where_predicate<'a, V: Visitor<'a>>(
1220 visitor: &mut V,
1221 predicate: &'a WherePredicate,
1222) -> V::Result {
1223 let WherePredicate { attrs, kind, id: _, span: _, is_placeholder: _ } = predicate;
1224 walk_list!(visitor, visit_attribute, attrs);
1225 visitor.visit_where_predicate_kind(kind)
1226}
1227
1228pub fn walk_where_predicate_kind<'a, V: Visitor<'a>>(
1229 visitor: &mut V,
1230 kind: &'a WherePredicateKind,
1231) -> V::Result {
1232 match kind {
1233 WherePredicateKind::BoundPredicate(WhereBoundPredicate {
1234 bounded_ty,
1235 bounds,
1236 bound_generic_params,
1237 }) => {
1238 walk_list!(visitor, visit_generic_param, bound_generic_params);
1239 try_visit!(visitor.visit_ty(bounded_ty));
1240 walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
1241 }
1242 WherePredicateKind::RegionPredicate(WhereRegionPredicate { lifetime, bounds }) => {
1243 try_visit!(visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound));
1244 walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
1245 }
1246 WherePredicateKind::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty }) => {
1247 try_visit!(visitor.visit_ty(lhs_ty));
1248 try_visit!(visitor.visit_ty(rhs_ty));
1249 }
1250 }
1251 V::Result::output()
1252}
1253
1254pub fn walk_fn_ret_ty<'a, V: Visitor<'a>>(visitor: &mut V, ret_ty: &'a FnRetTy) -> V::Result {
1255 match ret_ty {
1256 FnRetTy::Default(_span) => {}
1257 FnRetTy::Ty(output_ty) => try_visit!(visitor.visit_ty(output_ty)),
1258 }
1259 V::Result::output()
1260}
1261
1262pub fn walk_fn_decl<'a, V: Visitor<'a>>(
1263 visitor: &mut V,
1264 FnDecl { inputs, output }: &'a FnDecl,
1265) -> V::Result {
1266 walk_list!(visitor, visit_param, inputs);
1267 visitor.visit_fn_ret_ty(output)
1268}
1269
1270pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Result {
1271 match kind {
1272 FnKind::Fn(
1273 _ctxt,
1274 _vis,
1275 Fn {
1276 defaultness: _,
1277 ident,
1278 sig: FnSig { header, decl, span: _ },
1279 generics,
1280 contract,
1281 body,
1282 define_opaque,
1283 },
1284 ) => {
1285 try_visit!(visitor.visit_ident(ident));
1287 try_visit!(visitor.visit_fn_header(header));
1288 try_visit!(visitor.visit_generics(generics));
1289 try_visit!(visitor.visit_fn_decl(decl));
1290 visit_opt!(visitor, visit_contract, contract);
1291 visit_opt!(visitor, visit_block, body);
1292 try_visit!(walk_define_opaques(visitor, define_opaque));
1293 }
1294 FnKind::Closure(binder, coroutine_kind, decl, body) => {
1295 try_visit!(visitor.visit_closure_binder(binder));
1296 visit_opt!(visitor, visit_coroutine_kind, coroutine_kind.as_ref());
1297 try_visit!(visitor.visit_fn_decl(decl));
1298 try_visit!(visitor.visit_expr(body));
1299 }
1300 }
1301 V::Result::output()
1302}
1303
1304pub fn walk_variant_data<'a, V: Visitor<'a>>(visitor: &mut V, data: &'a VariantData) -> V::Result {
1305 visit_opt!(visitor, visit_id, data.ctor_node_id());
1306 walk_list!(visitor, visit_field_def, data.fields());
1307 V::Result::output()
1308}
1309
1310pub fn walk_field_def<'a, V: Visitor<'a>>(visitor: &mut V, field: &'a FieldDef) -> V::Result {
1311 let FieldDef { attrs, id: _, span: _, vis, ident, ty, is_placeholder: _, safety: _, default } =
1312 field;
1313 walk_list!(visitor, visit_attribute, attrs);
1314 try_visit!(visitor.visit_vis(vis));
1315 visit_opt!(visitor, visit_ident, ident);
1316 try_visit!(visitor.visit_ty(ty));
1317 visit_opt!(visitor, visit_anon_const, &*default);
1318 V::Result::output()
1319}
1320
1321pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) -> V::Result {
1322 let Stmt { id: _, kind, span: _ } = statement;
1323 match kind {
1324 StmtKind::Let(local) => try_visit!(visitor.visit_local(local)),
1325 StmtKind::Item(item) => try_visit!(visitor.visit_item(item)),
1326 StmtKind::Expr(expr) | StmtKind::Semi(expr) => try_visit!(visitor.visit_expr(expr)),
1327 StmtKind::Empty => {}
1328 StmtKind::MacCall(mac) => {
1329 let MacCallStmt { mac, attrs, style: _, tokens: _ } = &**mac;
1330 walk_list!(visitor, visit_attribute, attrs);
1331 try_visit!(visitor.visit_mac_call(mac));
1332 }
1333 }
1334 V::Result::output()
1335}
1336
1337pub fn walk_mac<'a, V: Visitor<'a>>(visitor: &mut V, mac: &'a MacCall) -> V::Result {
1338 let MacCall { path, args: _ } = mac;
1339 visitor.visit_path(path)
1340}
1341
1342pub fn walk_inline_asm<'a, V: Visitor<'a>>(visitor: &mut V, asm: &'a InlineAsm) -> V::Result {
1343 let InlineAsm {
1344 asm_macro: _,
1345 template: _,
1346 template_strs: _,
1347 operands,
1348 clobber_abis: _,
1349 options: _,
1350 line_spans: _,
1351 } = asm;
1352 for (op, _span) in operands {
1353 match op {
1354 InlineAsmOperand::In { expr, reg: _ }
1355 | InlineAsmOperand::Out { expr: Some(expr), reg: _, late: _ }
1356 | InlineAsmOperand::InOut { expr, reg: _, late: _ } => {
1357 try_visit!(visitor.visit_expr(expr))
1358 }
1359 InlineAsmOperand::Out { expr: None, reg: _, late: _ } => {}
1360 InlineAsmOperand::SplitInOut { in_expr, out_expr, reg: _, late: _ } => {
1361 try_visit!(visitor.visit_expr(in_expr));
1362 visit_opt!(visitor, visit_expr, out_expr);
1363 }
1364 InlineAsmOperand::Const { anon_const } => {
1365 try_visit!(visitor.visit_anon_const(anon_const))
1366 }
1367 InlineAsmOperand::Sym { sym } => try_visit!(visitor.visit_inline_asm_sym(sym)),
1368 InlineAsmOperand::Label { block } => try_visit!(visitor.visit_block(block)),
1369 }
1370 }
1371 V::Result::output()
1372}
1373
1374pub fn walk_inline_asm_sym<'a, V: Visitor<'a>>(
1375 visitor: &mut V,
1376 InlineAsmSym { id, qself, path }: &'a InlineAsmSym,
1377) -> V::Result {
1378 try_visit!(visitor.visit_qself(qself));
1379 try_visit!(visitor.visit_id(*id));
1380 visitor.visit_path(path)
1381}
1382
1383pub fn walk_format_args<'a, V: Visitor<'a>>(visitor: &mut V, fmt: &'a FormatArgs) -> V::Result {
1384 let FormatArgs { span: _, template: _, arguments, uncooked_fmt_str: _ } = fmt;
1385 for FormatArgument { kind, expr } in arguments.all_args() {
1386 match kind {
1387 FormatArgumentKind::Named(ident) | FormatArgumentKind::Captured(ident) => {
1388 try_visit!(visitor.visit_ident(ident))
1389 }
1390 FormatArgumentKind::Normal => {}
1391 }
1392 try_visit!(visitor.visit_expr(expr));
1393 }
1394 V::Result::output()
1395}
1396
1397pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V::Result {
1398 let Expr { id, kind, span, attrs, tokens: _ } = expression;
1399 walk_list!(visitor, visit_attribute, attrs);
1400 match kind {
1401 ExprKind::Array(subexpressions) => {
1402 walk_list!(visitor, visit_expr, subexpressions);
1403 }
1404 ExprKind::ConstBlock(anon_const) => try_visit!(visitor.visit_anon_const(anon_const)),
1405 ExprKind::Repeat(element, count) => {
1406 try_visit!(visitor.visit_expr(element));
1407 try_visit!(visitor.visit_anon_const(count));
1408 }
1409 ExprKind::Struct(se) => {
1410 let StructExpr { qself, path, fields, rest } = &**se;
1411 try_visit!(visitor.visit_qself(qself));
1412 try_visit!(visitor.visit_id(*id));
1413 try_visit!(visitor.visit_path(path));
1414 walk_list!(visitor, visit_expr_field, fields);
1415 match rest {
1416 StructRest::Base(expr) => try_visit!(visitor.visit_expr(expr)),
1417 StructRest::Rest(_span) => {}
1418 StructRest::None => {}
1419 }
1420 }
1421 ExprKind::Tup(subexpressions) => {
1422 walk_list!(visitor, visit_expr, subexpressions);
1423 }
1424 ExprKind::Call(callee_expression, arguments) => {
1425 try_visit!(visitor.visit_expr(callee_expression));
1426 walk_list!(visitor, visit_expr, arguments);
1427 }
1428 ExprKind::MethodCall(box MethodCall { seg, receiver, args, span: _ }) => {
1429 try_visit!(visitor.visit_expr(receiver));
1430 try_visit!(visitor.visit_path_segment(seg));
1431 walk_list!(visitor, visit_expr, args);
1432 }
1433 ExprKind::Binary(_op, left_expression, right_expression) => {
1434 try_visit!(visitor.visit_expr(left_expression));
1435 try_visit!(visitor.visit_expr(right_expression));
1436 }
1437 ExprKind::AddrOf(_kind, _mutbl, subexpression) => {
1438 try_visit!(visitor.visit_expr(subexpression));
1439 }
1440 ExprKind::Unary(_op, subexpression) => {
1441 try_visit!(visitor.visit_expr(subexpression));
1442 }
1443 ExprKind::Cast(subexpression, typ) | ExprKind::Type(subexpression, typ) => {
1444 try_visit!(visitor.visit_expr(subexpression));
1445 try_visit!(visitor.visit_ty(typ));
1446 }
1447 ExprKind::Let(pat, expr, _span, _recovered) => {
1448 try_visit!(visitor.visit_pat(pat));
1449 try_visit!(visitor.visit_expr(expr));
1450 }
1451 ExprKind::If(head_expression, if_block, optional_else) => {
1452 try_visit!(visitor.visit_expr(head_expression));
1453 try_visit!(visitor.visit_block(if_block));
1454 visit_opt!(visitor, visit_expr, optional_else);
1455 }
1456 ExprKind::While(subexpression, block, opt_label) => {
1457 visit_opt!(visitor, visit_label, opt_label);
1458 try_visit!(visitor.visit_expr(subexpression));
1459 try_visit!(visitor.visit_block(block));
1460 }
1461 ExprKind::ForLoop { pat, iter, body, label, kind: _ } => {
1462 visit_opt!(visitor, visit_label, label);
1463 try_visit!(visitor.visit_pat(pat));
1464 try_visit!(visitor.visit_expr(iter));
1465 try_visit!(visitor.visit_block(body));
1466 }
1467 ExprKind::Loop(block, opt_label, _span) => {
1468 visit_opt!(visitor, visit_label, opt_label);
1469 try_visit!(visitor.visit_block(block));
1470 }
1471 ExprKind::Match(subexpression, arms, _kind) => {
1472 try_visit!(visitor.visit_expr(subexpression));
1473 walk_list!(visitor, visit_arm, arms);
1474 }
1475 ExprKind::Closure(box Closure {
1476 binder,
1477 capture_clause,
1478 coroutine_kind,
1479 constness: _,
1480 movability: _,
1481 fn_decl,
1482 body,
1483 fn_decl_span: _,
1484 fn_arg_span: _,
1485 }) => {
1486 try_visit!(visitor.visit_capture_by(capture_clause));
1487 try_visit!(visitor.visit_fn(
1488 FnKind::Closure(binder, coroutine_kind, fn_decl, body),
1489 *span,
1490 *id
1491 ));
1492 }
1493 ExprKind::Block(block, opt_label) => {
1494 visit_opt!(visitor, visit_label, opt_label);
1495 try_visit!(visitor.visit_block(block));
1496 }
1497 ExprKind::Gen(_capt, body, _kind, _decl_span) => try_visit!(visitor.visit_block(body)),
1498 ExprKind::Await(expr, _span) => try_visit!(visitor.visit_expr(expr)),
1499 ExprKind::Use(expr, _span) => try_visit!(visitor.visit_expr(expr)),
1500 ExprKind::Assign(lhs, rhs, _span) => {
1501 try_visit!(visitor.visit_expr(lhs));
1502 try_visit!(visitor.visit_expr(rhs));
1503 }
1504 ExprKind::AssignOp(_op, left_expression, right_expression) => {
1505 try_visit!(visitor.visit_expr(left_expression));
1506 try_visit!(visitor.visit_expr(right_expression));
1507 }
1508 ExprKind::Field(subexpression, ident) => {
1509 try_visit!(visitor.visit_expr(subexpression));
1510 try_visit!(visitor.visit_ident(ident));
1511 }
1512 ExprKind::Index(main_expression, index_expression, _span) => {
1513 try_visit!(visitor.visit_expr(main_expression));
1514 try_visit!(visitor.visit_expr(index_expression));
1515 }
1516 ExprKind::Range(start, end, _limit) => {
1517 visit_opt!(visitor, visit_expr, start);
1518 visit_opt!(visitor, visit_expr, end);
1519 }
1520 ExprKind::Underscore => {}
1521 ExprKind::Path(maybe_qself, path) => {
1522 try_visit!(visitor.visit_qself(maybe_qself));
1523 try_visit!(visitor.visit_id(*id));
1524 try_visit!(visitor.visit_path(path));
1525 }
1526 ExprKind::Break(opt_label, opt_expr) => {
1527 visit_opt!(visitor, visit_label, opt_label);
1528 visit_opt!(visitor, visit_expr, opt_expr);
1529 }
1530 ExprKind::Continue(opt_label) => {
1531 visit_opt!(visitor, visit_label, opt_label);
1532 }
1533 ExprKind::Ret(optional_expression) => {
1534 visit_opt!(visitor, visit_expr, optional_expression);
1535 }
1536 ExprKind::Yeet(optional_expression) => {
1537 visit_opt!(visitor, visit_expr, optional_expression);
1538 }
1539 ExprKind::Become(expr) => try_visit!(visitor.visit_expr(expr)),
1540 ExprKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)),
1541 ExprKind::Paren(subexpression) => try_visit!(visitor.visit_expr(subexpression)),
1542 ExprKind::InlineAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)),
1543 ExprKind::FormatArgs(f) => try_visit!(visitor.visit_format_args(f)),
1544 ExprKind::OffsetOf(container, fields) => {
1545 try_visit!(visitor.visit_ty(container));
1546 walk_list!(visitor, visit_ident, fields.iter());
1547 }
1548 ExprKind::Yield(kind) => {
1549 visit_opt!(visitor, visit_expr, kind.expr());
1550 }
1551 ExprKind::Try(subexpression) => try_visit!(visitor.visit_expr(subexpression)),
1552 ExprKind::TryBlock(body) => try_visit!(visitor.visit_block(body)),
1553 ExprKind::Lit(_token) => {}
1554 ExprKind::IncludedBytes(_bytes) => {}
1555 ExprKind::UnsafeBinderCast(_kind, expr, ty) => {
1556 try_visit!(visitor.visit_expr(expr));
1557 visit_opt!(visitor, visit_ty, ty);
1558 }
1559 ExprKind::Err(_guar) => {}
1560 ExprKind::Dummy => {}
1561 }
1562
1563 V::Result::output()
1564}
1565
1566pub fn walk_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a Param) -> V::Result {
1567 let Param { attrs, ty, pat, id: _, span: _, is_placeholder: _ } = param;
1568 walk_list!(visitor, visit_attribute, attrs);
1569 try_visit!(visitor.visit_pat(pat));
1570 try_visit!(visitor.visit_ty(ty));
1571 V::Result::output()
1572}
1573
1574pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) -> V::Result {
1575 let Arm { attrs, pat, guard, body, span: _, id: _, is_placeholder: _ } = arm;
1576 walk_list!(visitor, visit_attribute, attrs);
1577 try_visit!(visitor.visit_pat(pat));
1578 visit_opt!(visitor, visit_expr, guard);
1579 visit_opt!(visitor, visit_expr, body);
1580 V::Result::output()
1581}
1582
1583pub fn walk_vis<'a, V: Visitor<'a>>(visitor: &mut V, vis: &'a Visibility) -> V::Result {
1584 let Visibility { kind, span: _, tokens: _ } = vis;
1585 match kind {
1586 VisibilityKind::Restricted { path, id, shorthand: _ } => {
1587 try_visit!(visitor.visit_id(*id));
1588 try_visit!(visitor.visit_path(path));
1589 }
1590 VisibilityKind::Public | VisibilityKind::Inherited => {}
1591 }
1592 V::Result::output()
1593}
1594
1595pub fn walk_attribute<'a, V: Visitor<'a>>(visitor: &mut V, attr: &'a Attribute) -> V::Result {
1596 let Attribute { kind, id: _, style: _, span: _ } = attr;
1597 match kind {
1598 AttrKind::Normal(normal) => {
1599 let NormalAttr { item, tokens: _ } = &**normal;
1600 let AttrItem { unsafety: _, path, args, tokens: _ } = item;
1601 try_visit!(visitor.visit_path(path));
1602 try_visit!(walk_attr_args(visitor, args));
1603 }
1604 AttrKind::DocComment(_kind, _sym) => {}
1605 }
1606 V::Result::output()
1607}
1608
1609pub fn walk_attr_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a AttrArgs) -> V::Result {
1610 match args {
1611 AttrArgs::Empty => {}
1612 AttrArgs::Delimited(_args) => {}
1613 AttrArgs::Eq { expr, .. } => try_visit!(visitor.visit_expr(expr)),
1614 }
1615 V::Result::output()
1616}