1 //! AST walker. Each overridden visit method has full control over what
2 //! happens with its node, it can do its own traversal of the node's children,
3 //! call `visit::walk_*` to apply the default traversal algorithm, or prevent
4 //! deeper traversal by doing nothing.
6 //! Note: it is an important invariant that the default visitor walks the body
7 //! of a function in "execution order" (more concretely, reverse post-order
8 //! with respect to the CFG implied by the AST), meaning that if AST node A may
9 //! execute before AST node B, then A is visited first. The borrow checker in
10 //! particular relies on this property.
12 //! Note: walking an AST before macro expansion is probably a bad idea. For
13 //! instance, a walker looking for item names in a module will miss all of
14 //! those that are created by the expansion of a macro.
16 use crate::{ast::*, StaticItem}
;
18 use rustc_span
::symbol
::Ident
;
21 #[derive(Copy, Clone, Debug, PartialEq)]
27 #[derive(Copy, Clone, Debug, PartialEq)]
34 #[derive(Copy, Clone, Debug)]
36 /// Trait bounds in generics bounds and type/trait alias.
37 /// E.g., `<T: Bound>`, `type A: Bound`, or `where T: Bound`.
40 /// Trait bounds in `impl` type.
41 /// E.g., `type Foo = impl Bound1 + Bound2 + Bound3`.
44 /// Trait bounds in trait object type.
45 /// E.g., `dyn Bound1 + Bound2 + Bound3`.
48 /// Super traits of a trait.
49 /// E.g., `trait A: B`
53 #[derive(Copy, Clone, Debug)]
55 /// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`.
56 Fn(FnCtxt
, Ident
, &'a FnSig
, &'a Visibility
, &'a Generics
, Option
<&'a Block
>),
58 /// E.g., `|x, y| body`.
59 Closure(&'a ClosureBinder
, &'a FnDecl
, &'a Expr
),
63 pub fn header(&self) -> Option
<&'a FnHeader
> {
65 FnKind
::Fn(_
, _
, sig
, _
, _
, _
) => Some(&sig
.header
),
66 FnKind
::Closure(_
, _
, _
) => None
,
70 pub fn ident(&self) -> Option
<&Ident
> {
72 FnKind
::Fn(_
, ident
, ..) => Some(ident
),
77 pub fn decl(&self) -> &'a FnDecl
{
79 FnKind
::Fn(_
, _
, sig
, _
, _
, _
) => &sig
.decl
,
80 FnKind
::Closure(_
, decl
, _
) => decl
,
84 pub fn ctxt(&self) -> Option
<FnCtxt
> {
86 FnKind
::Fn(ctxt
, ..) => Some(*ctxt
),
87 FnKind
::Closure(..) => None
,
92 #[derive(Copy, Clone, Debug)]
93 pub enum LifetimeCtxt
{
94 /// Appears in a reference type.
96 /// Appears as a bound on a type or another lifetime.
98 /// Appears as a generic argument.
102 /// Each method of the `Visitor` trait is a hook to be potentially
103 /// overridden. Each method's default implementation recursively visits
104 /// the substructure of the input via the corresponding `walk` method;
105 /// e.g., the `visit_item` method by default calls `visit::walk_item`.
107 /// If you want to ensure that your code handles every variant
108 /// explicitly, you need to override each method. (And you also need
109 /// to monitor future changes to `Visitor` in case a new method with a
110 /// new default implementation gets introduced.)
111 pub trait Visitor
<'ast
>: Sized
{
112 fn visit_ident(&mut self, _ident
: Ident
) {}
113 fn visit_foreign_item(&mut self, i
: &'ast ForeignItem
) {
114 walk_foreign_item(self, i
)
116 fn visit_item(&mut self, i
: &'ast Item
) {
119 fn visit_local(&mut self, l
: &'ast Local
) {
122 fn visit_block(&mut self, b
: &'ast Block
) {
125 fn visit_stmt(&mut self, s
: &'ast Stmt
) {
128 fn visit_param(&mut self, param
: &'ast Param
) {
129 walk_param(self, param
)
131 fn visit_arm(&mut self, a
: &'ast Arm
) {
134 fn visit_pat(&mut self, p
: &'ast Pat
) {
137 fn visit_anon_const(&mut self, c
: &'ast AnonConst
) {
138 walk_anon_const(self, c
)
140 fn visit_expr(&mut self, ex
: &'ast Expr
) {
143 /// This method is a hack to workaround unstable of `stmt_expr_attributes`.
144 /// It can be removed once that feature is stabilized.
145 fn visit_method_receiver_expr(&mut self, ex
: &'ast Expr
) {
148 fn visit_expr_post(&mut self, _ex
: &'ast Expr
) {}
149 fn visit_ty(&mut self, t
: &'ast Ty
) {
152 fn visit_generic_param(&mut self, param
: &'ast GenericParam
) {
153 walk_generic_param(self, param
)
155 fn visit_generics(&mut self, g
: &'ast Generics
) {
156 walk_generics(self, g
)
158 fn visit_closure_binder(&mut self, b
: &'ast ClosureBinder
) {
159 walk_closure_binder(self, b
)
161 fn visit_where_predicate(&mut self, p
: &'ast WherePredicate
) {
162 walk_where_predicate(self, p
)
164 fn visit_fn(&mut self, fk
: FnKind
<'ast
>, _
: Span
, _
: NodeId
) {
167 fn visit_assoc_item(&mut self, i
: &'ast AssocItem
, ctxt
: AssocCtxt
) {
168 walk_assoc_item(self, i
, ctxt
)
170 fn visit_trait_ref(&mut self, t
: &'ast TraitRef
) {
171 walk_trait_ref(self, t
)
173 fn visit_param_bound(&mut self, bounds
: &'ast GenericBound
, _ctxt
: BoundKind
) {
174 walk_param_bound(self, bounds
)
176 fn visit_poly_trait_ref(&mut self, t
: &'ast PolyTraitRef
) {
177 walk_poly_trait_ref(self, t
)
179 fn visit_variant_data(&mut self, s
: &'ast VariantData
) {
180 walk_struct_def(self, s
)
182 fn visit_field_def(&mut self, s
: &'ast FieldDef
) {
183 walk_field_def(self, s
)
185 fn visit_enum_def(&mut self, enum_definition
: &'ast EnumDef
) {
186 walk_enum_def(self, enum_definition
)
188 fn visit_variant(&mut self, v
: &'ast Variant
) {
189 walk_variant(self, v
)
191 fn visit_variant_discr(&mut self, discr
: &'ast AnonConst
) {
192 self.visit_anon_const(discr
);
194 fn visit_label(&mut self, label
: &'ast Label
) {
195 walk_label(self, label
)
197 fn visit_lifetime(&mut self, lifetime
: &'ast Lifetime
, _
: LifetimeCtxt
) {
198 walk_lifetime(self, lifetime
)
200 fn visit_mac_call(&mut self, mac
: &'ast MacCall
) {
203 fn visit_mac_def(&mut self, _mac
: &'ast MacroDef
, _id
: NodeId
) {
206 fn visit_path(&mut self, path
: &'ast Path
, _id
: NodeId
) {
207 walk_path(self, path
)
209 fn visit_use_tree(&mut self, use_tree
: &'ast UseTree
, id
: NodeId
, _nested
: bool
) {
210 walk_use_tree(self, use_tree
, id
)
212 fn visit_path_segment(&mut self, path_segment
: &'ast PathSegment
) {
213 walk_path_segment(self, path_segment
)
215 fn visit_generic_args(&mut self, generic_args
: &'ast GenericArgs
) {
216 walk_generic_args(self, generic_args
)
218 fn visit_generic_arg(&mut self, generic_arg
: &'ast GenericArg
) {
219 walk_generic_arg(self, generic_arg
)
221 fn visit_assoc_constraint(&mut self, constraint
: &'ast AssocConstraint
) {
222 walk_assoc_constraint(self, constraint
)
224 fn visit_attribute(&mut self, attr
: &'ast Attribute
) {
225 walk_attribute(self, attr
)
227 fn visit_vis(&mut self, vis
: &'ast Visibility
) {
230 fn visit_fn_ret_ty(&mut self, ret_ty
: &'ast FnRetTy
) {
231 walk_fn_ret_ty(self, ret_ty
)
233 fn visit_fn_header(&mut self, _header
: &'ast FnHeader
) {
236 fn visit_expr_field(&mut self, f
: &'ast ExprField
) {
237 walk_expr_field(self, f
)
239 fn visit_pat_field(&mut self, fp
: &'ast PatField
) {
240 walk_pat_field(self, fp
)
242 fn visit_crate(&mut self, krate
: &'ast Crate
) {
243 walk_crate(self, krate
)
245 fn visit_inline_asm(&mut self, asm
: &'ast InlineAsm
) {
246 walk_inline_asm(self, asm
)
248 fn visit_format_args(&mut self, fmt
: &'ast FormatArgs
) {
249 walk_format_args(self, fmt
)
251 fn visit_inline_asm_sym(&mut self, sym
: &'ast InlineAsmSym
) {
252 walk_inline_asm_sym(self, sym
)
257 macro_rules
! walk_list
{
258 ($visitor
: expr
, $method
: ident
, $list
: expr $
(, $
($extra_args
: expr
),* )?
) => {
260 #[allow(for_loops_over_fallibles)]
262 $visitor
.$
method(elem $
(, $
($extra_args
,)* )?
)
268 pub fn walk_crate
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, krate
: &'a Crate
) {
269 walk_list
!(visitor
, visit_item
, &krate
.items
);
270 walk_list
!(visitor
, visit_attribute
, &krate
.attrs
);
273 pub fn walk_local
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, local
: &'a Local
) {
274 for attr
in local
.attrs
.iter() {
275 visitor
.visit_attribute(attr
);
277 visitor
.visit_pat(&local
.pat
);
278 walk_list
!(visitor
, visit_ty
, &local
.ty
);
279 if let Some((init
, els
)) = local
.kind
.init_else_opt() {
280 visitor
.visit_expr(init
);
281 walk_list
!(visitor
, visit_block
, els
);
285 pub fn walk_label
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, label
: &'a Label
) {
286 visitor
.visit_ident(label
.ident
);
289 pub fn walk_lifetime
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, lifetime
: &'a Lifetime
) {
290 visitor
.visit_ident(lifetime
.ident
);
293 pub fn walk_poly_trait_ref
<'a
, V
>(visitor
: &mut V
, trait_ref
: &'a PolyTraitRef
)
297 walk_list
!(visitor
, visit_generic_param
, &trait_ref
.bound_generic_params
);
298 visitor
.visit_trait_ref(&trait_ref
.trait_ref
);
301 pub fn walk_trait_ref
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, trait_ref
: &'a TraitRef
) {
302 visitor
.visit_path(&trait_ref
.path
, trait_ref
.ref_id
)
305 pub fn walk_item
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, item
: &'a Item
) {
306 visitor
.visit_vis(&item
.vis
);
307 visitor
.visit_ident(item
.ident
);
309 ItemKind
::ExternCrate(_
) => {}
310 ItemKind
::Use(use_tree
) => visitor
.visit_use_tree(use_tree
, item
.id
, false),
311 ItemKind
::Static(box StaticItem { ty, mutability: _, expr }
)
312 | ItemKind
::Const(box ConstItem { ty, expr, .. }
) => {
313 visitor
.visit_ty(ty
);
314 walk_list
!(visitor
, visit_expr
, expr
);
316 ItemKind
::Fn(box Fn { defaultness: _, generics, sig, body }
) => {
318 FnKind
::Fn(FnCtxt
::Free
, item
.ident
, sig
, &item
.vis
, generics
, body
.as_deref());
319 visitor
.visit_fn(kind
, item
.span
, item
.id
)
321 ItemKind
::Mod(_unsafety
, mod_kind
) => match mod_kind
{
322 ModKind
::Loaded(items
, _inline
, _inner_span
) => {
323 walk_list
!(visitor
, visit_item
, items
)
325 ModKind
::Unloaded
=> {}
327 ItemKind
::ForeignMod(foreign_module
) => {
328 walk_list
!(visitor
, visit_foreign_item
, &foreign_module
.items
);
330 ItemKind
::GlobalAsm(asm
) => visitor
.visit_inline_asm(asm
),
331 ItemKind
::TyAlias(box TyAlias { generics, bounds, ty, .. }
) => {
332 visitor
.visit_generics(generics
);
333 walk_list
!(visitor
, visit_param_bound
, bounds
, BoundKind
::Bound
);
334 walk_list
!(visitor
, visit_ty
, ty
);
336 ItemKind
::Enum(enum_definition
, generics
) => {
337 visitor
.visit_generics(generics
);
338 visitor
.visit_enum_def(enum_definition
)
340 ItemKind
::Impl(box Impl
{
350 visitor
.visit_generics(generics
);
351 walk_list
!(visitor
, visit_trait_ref
, of_trait
);
352 visitor
.visit_ty(self_ty
);
353 walk_list
!(visitor
, visit_assoc_item
, items
, AssocCtxt
::Impl
);
355 ItemKind
::Struct(struct_definition
, generics
)
356 | ItemKind
::Union(struct_definition
, generics
) => {
357 visitor
.visit_generics(generics
);
358 visitor
.visit_variant_data(struct_definition
);
360 ItemKind
::Trait(box Trait { unsafety: _, is_auto: _, generics, bounds, items }
) => {
361 visitor
.visit_generics(generics
);
362 walk_list
!(visitor
, visit_param_bound
, bounds
, BoundKind
::SuperTraits
);
363 walk_list
!(visitor
, visit_assoc_item
, items
, AssocCtxt
::Trait
);
365 ItemKind
::TraitAlias(generics
, bounds
) => {
366 visitor
.visit_generics(generics
);
367 walk_list
!(visitor
, visit_param_bound
, bounds
, BoundKind
::Bound
);
369 ItemKind
::MacCall(mac
) => visitor
.visit_mac_call(mac
),
370 ItemKind
::MacroDef(ts
) => visitor
.visit_mac_def(ts
, item
.id
),
372 walk_list
!(visitor
, visit_attribute
, &item
.attrs
);
375 pub fn walk_enum_def
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, enum_definition
: &'a EnumDef
) {
376 walk_list
!(visitor
, visit_variant
, &enum_definition
.variants
);
379 pub fn walk_variant
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, variant
: &'a Variant
)
383 visitor
.visit_ident(variant
.ident
);
384 visitor
.visit_vis(&variant
.vis
);
385 visitor
.visit_variant_data(&variant
.data
);
386 walk_list
!(visitor
, visit_variant_discr
, &variant
.disr_expr
);
387 walk_list
!(visitor
, visit_attribute
, &variant
.attrs
);
390 pub fn walk_expr_field
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, f
: &'a ExprField
) {
391 visitor
.visit_expr(&f
.expr
);
392 visitor
.visit_ident(f
.ident
);
393 walk_list
!(visitor
, visit_attribute
, f
.attrs
.iter());
396 pub fn walk_pat_field
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, fp
: &'a PatField
) {
397 visitor
.visit_ident(fp
.ident
);
398 visitor
.visit_pat(&fp
.pat
);
399 walk_list
!(visitor
, visit_attribute
, fp
.attrs
.iter());
402 pub fn walk_ty
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, typ
: &'a Ty
) {
404 TyKind
::Slice(ty
) | TyKind
::Paren(ty
) => visitor
.visit_ty(ty
),
405 TyKind
::Ptr(mutable_type
) => visitor
.visit_ty(&mutable_type
.ty
),
406 TyKind
::Ref(opt_lifetime
, mutable_type
) => {
407 walk_list
!(visitor
, visit_lifetime
, opt_lifetime
, LifetimeCtxt
::Ref
);
408 visitor
.visit_ty(&mutable_type
.ty
)
410 TyKind
::Tup(tuple_element_types
) => {
411 walk_list
!(visitor
, visit_ty
, tuple_element_types
);
413 TyKind
::BareFn(function_declaration
) => {
414 walk_list
!(visitor
, visit_generic_param
, &function_declaration
.generic_params
);
415 walk_fn_decl(visitor
, &function_declaration
.decl
);
417 TyKind
::Path(maybe_qself
, path
) => {
418 if let Some(qself
) = maybe_qself
{
419 visitor
.visit_ty(&qself
.ty
);
421 visitor
.visit_path(path
, typ
.id
);
423 TyKind
::Array(ty
, length
) => {
424 visitor
.visit_ty(ty
);
425 visitor
.visit_anon_const(length
)
427 TyKind
::TraitObject(bounds
, ..) => {
428 walk_list
!(visitor
, visit_param_bound
, bounds
, BoundKind
::TraitObject
);
430 TyKind
::ImplTrait(_
, bounds
) => {
431 walk_list
!(visitor
, visit_param_bound
, bounds
, BoundKind
::Impl
);
433 TyKind
::Typeof(expression
) => visitor
.visit_anon_const(expression
),
434 TyKind
::Infer
| TyKind
::ImplicitSelf
| TyKind
::Err
=> {}
435 TyKind
::MacCall(mac
) => visitor
.visit_mac_call(mac
),
436 TyKind
::Never
| TyKind
::CVarArgs
=> {}
440 pub fn walk_path
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, path
: &'a Path
) {
441 for segment
in &path
.segments
{
442 visitor
.visit_path_segment(segment
);
446 pub fn walk_use_tree
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, use_tree
: &'a UseTree
, id
: NodeId
) {
447 visitor
.visit_path(&use_tree
.prefix
, id
);
448 match &use_tree
.kind
{
449 UseTreeKind
::Simple(rename
) => {
450 // The extra IDs are handled during HIR lowering.
451 if let &Some(rename
) = rename
{
452 visitor
.visit_ident(rename
);
455 UseTreeKind
::Glob
=> {}
456 UseTreeKind
::Nested(use_trees
) => {
457 for &(ref nested_tree
, nested_id
) in use_trees
{
458 visitor
.visit_use_tree(nested_tree
, nested_id
, true);
464 pub fn walk_path_segment
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, segment
: &'a PathSegment
) {
465 visitor
.visit_ident(segment
.ident
);
466 if let Some(args
) = &segment
.args
{
467 visitor
.visit_generic_args(args
);
471 pub fn walk_generic_args
<'a
, V
>(visitor
: &mut V
, generic_args
: &'a GenericArgs
)
476 GenericArgs
::AngleBracketed(data
) => {
477 for arg
in &data
.args
{
479 AngleBracketedArg
::Arg(a
) => visitor
.visit_generic_arg(a
),
480 AngleBracketedArg
::Constraint(c
) => visitor
.visit_assoc_constraint(c
),
484 GenericArgs
::Parenthesized(data
) => {
485 walk_list
!(visitor
, visit_ty
, &data
.inputs
);
486 walk_fn_ret_ty(visitor
, &data
.output
);
491 pub fn walk_generic_arg
<'a
, V
>(visitor
: &mut V
, generic_arg
: &'a GenericArg
)
496 GenericArg
::Lifetime(lt
) => visitor
.visit_lifetime(lt
, LifetimeCtxt
::GenericArg
),
497 GenericArg
::Type(ty
) => visitor
.visit_ty(ty
),
498 GenericArg
::Const(ct
) => visitor
.visit_anon_const(ct
),
502 pub fn walk_assoc_constraint
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, constraint
: &'a AssocConstraint
) {
503 visitor
.visit_ident(constraint
.ident
);
504 if let Some(gen_args
) = &constraint
.gen_args
{
505 visitor
.visit_generic_args(gen_args
);
507 match &constraint
.kind
{
508 AssocConstraintKind
::Equality { term }
=> match term
{
509 Term
::Ty(ty
) => visitor
.visit_ty(ty
),
510 Term
::Const(c
) => visitor
.visit_anon_const(c
),
512 AssocConstraintKind
::Bound { bounds }
=> {
513 walk_list
!(visitor
, visit_param_bound
, bounds
, BoundKind
::Bound
);
518 pub fn walk_pat
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, pattern
: &'a Pat
) {
519 match &pattern
.kind
{
520 PatKind
::TupleStruct(opt_qself
, path
, elems
) => {
521 if let Some(qself
) = opt_qself
{
522 visitor
.visit_ty(&qself
.ty
);
524 visitor
.visit_path(path
, pattern
.id
);
525 walk_list
!(visitor
, visit_pat
, elems
);
527 PatKind
::Path(opt_qself
, path
) => {
528 if let Some(qself
) = opt_qself
{
529 visitor
.visit_ty(&qself
.ty
);
531 visitor
.visit_path(path
, pattern
.id
)
533 PatKind
::Struct(opt_qself
, path
, fields
, _
) => {
534 if let Some(qself
) = opt_qself
{
535 visitor
.visit_ty(&qself
.ty
);
537 visitor
.visit_path(path
, pattern
.id
);
538 walk_list
!(visitor
, visit_pat_field
, fields
);
540 PatKind
::Box(subpattern
) | PatKind
::Ref(subpattern
, _
) | PatKind
::Paren(subpattern
) => {
541 visitor
.visit_pat(subpattern
)
543 PatKind
::Ident(_
, ident
, optional_subpattern
) => {
544 visitor
.visit_ident(*ident
);
545 walk_list
!(visitor
, visit_pat
, optional_subpattern
);
547 PatKind
::Lit(expression
) => visitor
.visit_expr(expression
),
548 PatKind
::Range(lower_bound
, upper_bound
, _
) => {
549 walk_list
!(visitor
, visit_expr
, lower_bound
);
550 walk_list
!(visitor
, visit_expr
, upper_bound
);
552 PatKind
::Wild
| PatKind
::Rest
=> {}
553 PatKind
::Tuple(elems
) | PatKind
::Slice(elems
) | PatKind
::Or(elems
) => {
554 walk_list
!(visitor
, visit_pat
, elems
);
556 PatKind
::MacCall(mac
) => visitor
.visit_mac_call(mac
),
560 pub fn walk_foreign_item
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, item
: &'a ForeignItem
) {
561 let &Item { id, span, ident, ref vis, ref attrs, ref kind, tokens: _ }
= item
;
562 visitor
.visit_vis(vis
);
563 visitor
.visit_ident(ident
);
564 walk_list
!(visitor
, visit_attribute
, attrs
);
566 ForeignItemKind
::Static(ty
, _
, expr
) => {
567 visitor
.visit_ty(ty
);
568 walk_list
!(visitor
, visit_expr
, expr
);
570 ForeignItemKind
::Fn(box Fn { defaultness: _, generics, sig, body }
) => {
571 let kind
= FnKind
::Fn(FnCtxt
::Foreign
, ident
, sig
, vis
, generics
, body
.as_deref());
572 visitor
.visit_fn(kind
, span
, id
);
574 ForeignItemKind
::TyAlias(box TyAlias { generics, bounds, ty, .. }
) => {
575 visitor
.visit_generics(generics
);
576 walk_list
!(visitor
, visit_param_bound
, bounds
, BoundKind
::Bound
);
577 walk_list
!(visitor
, visit_ty
, ty
);
579 ForeignItemKind
::MacCall(mac
) => {
580 visitor
.visit_mac_call(mac
);
585 pub fn walk_param_bound
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, bound
: &'a GenericBound
) {
587 GenericBound
::Trait(typ
, _modifier
) => visitor
.visit_poly_trait_ref(typ
),
588 GenericBound
::Outlives(lifetime
) => visitor
.visit_lifetime(lifetime
, LifetimeCtxt
::Bound
),
592 pub fn walk_generic_param
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, param
: &'a GenericParam
) {
593 visitor
.visit_ident(param
.ident
);
594 walk_list
!(visitor
, visit_attribute
, param
.attrs
.iter());
595 walk_list
!(visitor
, visit_param_bound
, ¶m
.bounds
, BoundKind
::Bound
);
597 GenericParamKind
::Lifetime
=> (),
598 GenericParamKind
::Type { default }
=> walk_list
!(visitor
, visit_ty
, default),
599 GenericParamKind
::Const { ty, default, .. }
=> {
600 visitor
.visit_ty(ty
);
601 if let Some(default) = default {
602 visitor
.visit_anon_const(default);
608 pub fn walk_generics
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, generics
: &'a Generics
) {
609 walk_list
!(visitor
, visit_generic_param
, &generics
.params
);
610 walk_list
!(visitor
, visit_where_predicate
, &generics
.where_clause
.predicates
);
613 pub fn walk_closure_binder
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, binder
: &'a ClosureBinder
) {
615 ClosureBinder
::NotPresent
=> {}
616 ClosureBinder
::For { generic_params, span: _ }
=> {
617 walk_list
!(visitor
, visit_generic_param
, generic_params
)
622 pub fn walk_where_predicate
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, predicate
: &'a WherePredicate
) {
624 WherePredicate
::BoundPredicate(WhereBoundPredicate
{
627 bound_generic_params
,
630 visitor
.visit_ty(bounded_ty
);
631 walk_list
!(visitor
, visit_param_bound
, bounds
, BoundKind
::Bound
);
632 walk_list
!(visitor
, visit_generic_param
, bound_generic_params
);
634 WherePredicate
::RegionPredicate(WhereRegionPredicate { lifetime, bounds, .. }
) => {
635 visitor
.visit_lifetime(lifetime
, LifetimeCtxt
::Bound
);
636 walk_list
!(visitor
, visit_param_bound
, bounds
, BoundKind
::Bound
);
638 WherePredicate
::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, .. }
) => {
639 visitor
.visit_ty(lhs_ty
);
640 visitor
.visit_ty(rhs_ty
);
645 pub fn walk_fn_ret_ty
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, ret_ty
: &'a FnRetTy
) {
646 if let FnRetTy
::Ty(output_ty
) = ret_ty
{
647 visitor
.visit_ty(output_ty
)
651 pub fn walk_fn_decl
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, function_declaration
: &'a FnDecl
) {
652 for param
in &function_declaration
.inputs
{
653 visitor
.visit_param(param
);
655 visitor
.visit_fn_ret_ty(&function_declaration
.output
);
658 pub fn walk_fn
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, kind
: FnKind
<'a
>) {
660 FnKind
::Fn(_
, _
, sig
, _
, generics
, body
) => {
661 visitor
.visit_generics(generics
);
662 visitor
.visit_fn_header(&sig
.header
);
663 walk_fn_decl(visitor
, &sig
.decl
);
664 walk_list
!(visitor
, visit_block
, body
);
666 FnKind
::Closure(binder
, decl
, body
) => {
667 visitor
.visit_closure_binder(binder
);
668 walk_fn_decl(visitor
, decl
);
669 visitor
.visit_expr(body
);
674 pub fn walk_assoc_item
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, item
: &'a AssocItem
, ctxt
: AssocCtxt
) {
675 let &Item { id, span, ident, ref vis, ref attrs, ref kind, tokens: _ }
= item
;
676 visitor
.visit_vis(vis
);
677 visitor
.visit_ident(ident
);
678 walk_list
!(visitor
, visit_attribute
, attrs
);
680 AssocItemKind
::Const(box ConstItem { ty, expr, .. }
) => {
681 visitor
.visit_ty(ty
);
682 walk_list
!(visitor
, visit_expr
, expr
);
684 AssocItemKind
::Fn(box Fn { defaultness: _, generics, sig, body }
) => {
685 let kind
= FnKind
::Fn(FnCtxt
::Assoc(ctxt
), ident
, sig
, vis
, generics
, body
.as_deref());
686 visitor
.visit_fn(kind
, span
, id
);
688 AssocItemKind
::Type(box TyAlias { generics, bounds, ty, .. }
) => {
689 visitor
.visit_generics(generics
);
690 walk_list
!(visitor
, visit_param_bound
, bounds
, BoundKind
::Bound
);
691 walk_list
!(visitor
, visit_ty
, ty
);
693 AssocItemKind
::MacCall(mac
) => {
694 visitor
.visit_mac_call(mac
);
699 pub fn walk_struct_def
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, struct_definition
: &'a VariantData
) {
700 walk_list
!(visitor
, visit_field_def
, struct_definition
.fields());
703 pub fn walk_field_def
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, field
: &'a FieldDef
) {
704 visitor
.visit_vis(&field
.vis
);
705 if let Some(ident
) = field
.ident
{
706 visitor
.visit_ident(ident
);
708 visitor
.visit_ty(&field
.ty
);
709 walk_list
!(visitor
, visit_attribute
, &field
.attrs
);
712 pub fn walk_block
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, block
: &'a Block
) {
713 walk_list
!(visitor
, visit_stmt
, &block
.stmts
);
716 pub fn walk_stmt
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, statement
: &'a Stmt
) {
717 match &statement
.kind
{
718 StmtKind
::Local(local
) => visitor
.visit_local(local
),
719 StmtKind
::Item(item
) => visitor
.visit_item(item
),
720 StmtKind
::Expr(expr
) | StmtKind
::Semi(expr
) => visitor
.visit_expr(expr
),
721 StmtKind
::Empty
=> {}
722 StmtKind
::MacCall(mac
) => {
723 let MacCallStmt { mac, attrs, style: _, tokens: _ }
= &**mac
;
724 visitor
.visit_mac_call(mac
);
725 for attr
in attrs
.iter() {
726 visitor
.visit_attribute(attr
);
732 pub fn walk_mac
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, mac
: &'a MacCall
) {
733 visitor
.visit_path(&mac
.path
, DUMMY_NODE_ID
);
736 pub fn walk_anon_const
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, constant
: &'a AnonConst
) {
737 visitor
.visit_expr(&constant
.value
);
740 pub fn walk_inline_asm
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, asm
: &'a InlineAsm
) {
741 for (op
, _
) in &asm
.operands
{
743 InlineAsmOperand
::In { expr, .. }
744 | InlineAsmOperand
::Out { expr: Some(expr), .. }
745 | InlineAsmOperand
::InOut { expr, .. }
=> visitor
.visit_expr(expr
),
746 InlineAsmOperand
::Out { expr: None, .. }
=> {}
747 InlineAsmOperand
::SplitInOut { in_expr, out_expr, .. }
=> {
748 visitor
.visit_expr(in_expr
);
749 if let Some(out_expr
) = out_expr
{
750 visitor
.visit_expr(out_expr
);
753 InlineAsmOperand
::Const { anon_const, .. }
=> visitor
.visit_anon_const(anon_const
),
754 InlineAsmOperand
::Sym { sym }
=> visitor
.visit_inline_asm_sym(sym
),
759 pub fn walk_inline_asm_sym
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, sym
: &'a InlineAsmSym
) {
760 if let Some(qself
) = &sym
.qself
{
761 visitor
.visit_ty(&qself
.ty
);
763 visitor
.visit_path(&sym
.path
, sym
.id
);
766 pub fn walk_format_args
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, fmt
: &'a FormatArgs
) {
767 for arg
in fmt
.arguments
.all_args() {
768 if let FormatArgumentKind
::Named(name
) = arg
.kind
{
769 visitor
.visit_ident(name
);
771 visitor
.visit_expr(&arg
.expr
);
775 pub fn walk_expr
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, expression
: &'a Expr
) {
776 walk_list
!(visitor
, visit_attribute
, expression
.attrs
.iter());
778 match &expression
.kind
{
779 ExprKind
::Array(subexpressions
) => {
780 walk_list
!(visitor
, visit_expr
, subexpressions
);
782 ExprKind
::ConstBlock(anon_const
) => visitor
.visit_anon_const(anon_const
),
783 ExprKind
::Repeat(element
, count
) => {
784 visitor
.visit_expr(element
);
785 visitor
.visit_anon_const(count
)
787 ExprKind
::Struct(se
) => {
788 if let Some(qself
) = &se
.qself
{
789 visitor
.visit_ty(&qself
.ty
);
791 visitor
.visit_path(&se
.path
, expression
.id
);
792 walk_list
!(visitor
, visit_expr_field
, &se
.fields
);
794 StructRest
::Base(expr
) => visitor
.visit_expr(expr
),
795 StructRest
::Rest(_span
) => {}
796 StructRest
::None
=> {}
799 ExprKind
::Tup(subexpressions
) => {
800 walk_list
!(visitor
, visit_expr
, subexpressions
);
802 ExprKind
::Call(callee_expression
, arguments
) => {
803 visitor
.visit_expr(callee_expression
);
804 walk_list
!(visitor
, visit_expr
, arguments
);
806 ExprKind
::MethodCall(box MethodCall { seg, receiver, args, span: _ }
) => {
807 visitor
.visit_path_segment(seg
);
808 visitor
.visit_expr(receiver
);
809 walk_list
!(visitor
, visit_expr
, args
);
811 ExprKind
::Binary(_
, left_expression
, right_expression
) => {
812 visitor
.visit_expr(left_expression
);
813 visitor
.visit_expr(right_expression
)
815 ExprKind
::AddrOf(_
, _
, subexpression
) | ExprKind
::Unary(_
, subexpression
) => {
816 visitor
.visit_expr(subexpression
)
818 ExprKind
::Cast(subexpression
, typ
) | ExprKind
::Type(subexpression
, typ
) => {
819 visitor
.visit_expr(subexpression
);
820 visitor
.visit_ty(typ
)
822 ExprKind
::Let(pat
, expr
, _
) => {
823 visitor
.visit_pat(pat
);
824 visitor
.visit_expr(expr
);
826 ExprKind
::If(head_expression
, if_block
, optional_else
) => {
827 visitor
.visit_expr(head_expression
);
828 visitor
.visit_block(if_block
);
829 walk_list
!(visitor
, visit_expr
, optional_else
);
831 ExprKind
::While(subexpression
, block
, opt_label
) => {
832 walk_list
!(visitor
, visit_label
, opt_label
);
833 visitor
.visit_expr(subexpression
);
834 visitor
.visit_block(block
);
836 ExprKind
::ForLoop(pattern
, subexpression
, block
, opt_label
) => {
837 walk_list
!(visitor
, visit_label
, opt_label
);
838 visitor
.visit_pat(pattern
);
839 visitor
.visit_expr(subexpression
);
840 visitor
.visit_block(block
);
842 ExprKind
::Loop(block
, opt_label
, _
) => {
843 walk_list
!(visitor
, visit_label
, opt_label
);
844 visitor
.visit_block(block
);
846 ExprKind
::Match(subexpression
, arms
) => {
847 visitor
.visit_expr(subexpression
);
848 walk_list
!(visitor
, visit_arm
, arms
);
850 ExprKind
::Closure(box Closure
{
861 visitor
.visit_fn(FnKind
::Closure(binder
, fn_decl
, body
), expression
.span
, expression
.id
)
863 ExprKind
::Block(block
, opt_label
) => {
864 walk_list
!(visitor
, visit_label
, opt_label
);
865 visitor
.visit_block(block
);
867 ExprKind
::Async(_
, body
) => {
868 visitor
.visit_block(body
);
870 ExprKind
::Await(expr
, _
) => visitor
.visit_expr(expr
),
871 ExprKind
::Assign(lhs
, rhs
, _
) => {
872 visitor
.visit_expr(lhs
);
873 visitor
.visit_expr(rhs
);
875 ExprKind
::AssignOp(_
, left_expression
, right_expression
) => {
876 visitor
.visit_expr(left_expression
);
877 visitor
.visit_expr(right_expression
);
879 ExprKind
::Field(subexpression
, ident
) => {
880 visitor
.visit_expr(subexpression
);
881 visitor
.visit_ident(*ident
);
883 ExprKind
::Index(main_expression
, index_expression
) => {
884 visitor
.visit_expr(main_expression
);
885 visitor
.visit_expr(index_expression
)
887 ExprKind
::Range(start
, end
, _
) => {
888 walk_list
!(visitor
, visit_expr
, start
);
889 walk_list
!(visitor
, visit_expr
, end
);
891 ExprKind
::Underscore
=> {}
892 ExprKind
::Path(maybe_qself
, path
) => {
893 if let Some(qself
) = maybe_qself
{
894 visitor
.visit_ty(&qself
.ty
);
896 visitor
.visit_path(path
, expression
.id
)
898 ExprKind
::Break(opt_label
, opt_expr
) => {
899 walk_list
!(visitor
, visit_label
, opt_label
);
900 walk_list
!(visitor
, visit_expr
, opt_expr
);
902 ExprKind
::Continue(opt_label
) => {
903 walk_list
!(visitor
, visit_label
, opt_label
);
905 ExprKind
::Ret(optional_expression
) => {
906 walk_list
!(visitor
, visit_expr
, optional_expression
);
908 ExprKind
::Yeet(optional_expression
) => {
909 walk_list
!(visitor
, visit_expr
, optional_expression
);
911 ExprKind
::Become(expr
) => visitor
.visit_expr(expr
),
912 ExprKind
::MacCall(mac
) => visitor
.visit_mac_call(mac
),
913 ExprKind
::Paren(subexpression
) => visitor
.visit_expr(subexpression
),
914 ExprKind
::InlineAsm(asm
) => visitor
.visit_inline_asm(asm
),
915 ExprKind
::FormatArgs(f
) => visitor
.visit_format_args(f
),
916 ExprKind
::OffsetOf(container
, fields
) => {
917 visitor
.visit_ty(container
);
918 for &field
in fields
{
919 visitor
.visit_ident(field
);
922 ExprKind
::Yield(optional_expression
) => {
923 walk_list
!(visitor
, visit_expr
, optional_expression
);
925 ExprKind
::Try(subexpression
) => visitor
.visit_expr(subexpression
),
926 ExprKind
::TryBlock(body
) => visitor
.visit_block(body
),
927 ExprKind
::Lit(_
) | ExprKind
::IncludedBytes(..) | ExprKind
::Err
=> {}
930 visitor
.visit_expr_post(expression
)
933 pub fn walk_param
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, param
: &'a Param
) {
934 walk_list
!(visitor
, visit_attribute
, param
.attrs
.iter());
935 visitor
.visit_pat(¶m
.pat
);
936 visitor
.visit_ty(¶m
.ty
);
939 pub fn walk_arm
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, arm
: &'a Arm
) {
940 visitor
.visit_pat(&arm
.pat
);
941 walk_list
!(visitor
, visit_expr
, &arm
.guard
);
942 visitor
.visit_expr(&arm
.body
);
943 walk_list
!(visitor
, visit_attribute
, &arm
.attrs
);
946 pub fn walk_vis
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, vis
: &'a Visibility
) {
947 if let VisibilityKind
::Restricted { ref path, id, shorthand: _ }
= vis
.kind
{
948 visitor
.visit_path(path
, id
);
952 pub fn walk_attribute
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, attr
: &'a Attribute
) {
954 AttrKind
::Normal(normal
) => walk_attr_args(visitor
, &normal
.item
.args
),
955 AttrKind
::DocComment(..) => {}
959 pub fn walk_attr_args
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, args
: &'a AttrArgs
) {
961 AttrArgs
::Empty
=> {}
962 AttrArgs
::Delimited(_
) => {}
963 AttrArgs
::Eq(_eq_span
, AttrArgsEq
::Ast(expr
)) => visitor
.visit_expr(expr
),
964 AttrArgs
::Eq(_
, AttrArgsEq
::Hir(lit
)) => {
965 unreachable
!("in literal form when walking mac args eq: {:?}", lit
)