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.
19 use rustc_span
::symbol
::{Ident, Symbol}
;
22 #[derive(Copy, Clone, PartialEq)]
28 #[derive(Copy, Clone, PartialEq)]
35 #[derive(Copy, Clone)]
37 /// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`.
38 Fn(FnCtxt
, Ident
, &'a FnSig
, &'a Visibility
, Option
<&'a Block
>),
40 /// E.g., `|x, y| body`.
41 Closure(&'a FnDecl
, &'a Expr
),
45 pub fn header(&self) -> Option
<&'a FnHeader
> {
47 FnKind
::Fn(_
, _
, sig
, _
, _
) => Some(&sig
.header
),
48 FnKind
::Closure(_
, _
) => None
,
52 pub fn ident(&self) -> Option
<&Ident
> {
54 FnKind
::Fn(_
, ident
, ..) => Some(ident
),
59 pub fn decl(&self) -> &'a FnDecl
{
61 FnKind
::Fn(_
, _
, sig
, _
, _
) => &sig
.decl
,
62 FnKind
::Closure(decl
, _
) => decl
,
66 pub fn ctxt(&self) -> Option
<FnCtxt
> {
68 FnKind
::Fn(ctxt
, ..) => Some(*ctxt
),
69 FnKind
::Closure(..) => None
,
74 /// Each method of the `Visitor` trait is a hook to be potentially
75 /// overridden. Each method's default implementation recursively visits
76 /// the substructure of the input via the corresponding `walk` method;
77 /// e.g., the `visit_item` method by default calls `visit::walk_item`.
79 /// If you want to ensure that your code handles every variant
80 /// explicitly, you need to override each method. (And you also need
81 /// to monitor future changes to `Visitor` in case a new method with a
82 /// new default implementation gets introduced.)
83 pub trait Visitor
<'ast
>: Sized
{
84 fn visit_name(&mut self, _span
: Span
, _name
: Symbol
) {
87 fn visit_ident(&mut self, ident
: Ident
) {
88 walk_ident(self, ident
);
90 fn visit_foreign_item(&mut self, i
: &'ast ForeignItem
) {
91 walk_foreign_item(self, i
)
93 fn visit_global_asm(&mut self, ga
: &'ast GlobalAsm
) {
94 walk_global_asm(self, ga
)
96 fn visit_item(&mut self, i
: &'ast Item
) {
99 fn visit_local(&mut self, l
: &'ast Local
) {
102 fn visit_block(&mut self, b
: &'ast Block
) {
105 fn visit_stmt(&mut self, s
: &'ast Stmt
) {
108 fn visit_param(&mut self, param
: &'ast Param
) {
109 walk_param(self, param
)
111 fn visit_arm(&mut self, a
: &'ast Arm
) {
114 fn visit_pat(&mut self, p
: &'ast Pat
) {
117 fn visit_anon_const(&mut self, c
: &'ast AnonConst
) {
118 walk_anon_const(self, c
)
120 fn visit_expr(&mut self, ex
: &'ast Expr
) {
123 fn visit_expr_post(&mut self, _ex
: &'ast Expr
) {}
124 fn visit_ty(&mut self, t
: &'ast Ty
) {
127 fn visit_generic_param(&mut self, param
: &'ast GenericParam
) {
128 walk_generic_param(self, param
)
130 fn visit_generics(&mut self, g
: &'ast Generics
) {
131 walk_generics(self, g
)
133 fn visit_where_predicate(&mut self, p
: &'ast WherePredicate
) {
134 walk_where_predicate(self, p
)
136 fn visit_fn(&mut self, fk
: FnKind
<'ast
>, s
: Span
, _
: NodeId
) {
139 fn visit_assoc_item(&mut self, i
: &'ast AssocItem
, ctxt
: AssocCtxt
) {
140 walk_assoc_item(self, i
, ctxt
)
142 fn visit_trait_ref(&mut self, t
: &'ast TraitRef
) {
143 walk_trait_ref(self, t
)
145 fn visit_param_bound(&mut self, bounds
: &'ast GenericBound
) {
146 walk_param_bound(self, bounds
)
148 fn visit_poly_trait_ref(&mut self, t
: &'ast PolyTraitRef
, m
: &'ast TraitBoundModifier
) {
149 walk_poly_trait_ref(self, t
, m
)
151 fn visit_variant_data(&mut self, s
: &'ast VariantData
) {
152 walk_struct_def(self, s
)
154 fn visit_field_def(&mut self, s
: &'ast FieldDef
) {
155 walk_field_def(self, s
)
159 enum_definition
: &'ast EnumDef
,
160 generics
: &'ast Generics
,
164 walk_enum_def(self, enum_definition
, generics
, item_id
)
166 fn visit_variant(&mut self, v
: &'ast Variant
) {
167 walk_variant(self, v
)
169 fn visit_label(&mut self, label
: &'ast Label
) {
170 walk_label(self, label
)
172 fn visit_lifetime(&mut self, lifetime
: &'ast Lifetime
) {
173 walk_lifetime(self, lifetime
)
175 fn visit_mac_call(&mut self, mac
: &'ast MacCall
) {
178 fn visit_mac_def(&mut self, _mac
: &'ast MacroDef
, _id
: NodeId
) {
181 fn visit_path(&mut self, path
: &'ast Path
, _id
: NodeId
) {
182 walk_path(self, path
)
184 fn visit_use_tree(&mut self, use_tree
: &'ast UseTree
, id
: NodeId
, _nested
: bool
) {
185 walk_use_tree(self, use_tree
, id
)
187 fn visit_path_segment(&mut self, path_span
: Span
, path_segment
: &'ast PathSegment
) {
188 walk_path_segment(self, path_span
, path_segment
)
190 fn visit_generic_args(&mut self, path_span
: Span
, generic_args
: &'ast GenericArgs
) {
191 walk_generic_args(self, path_span
, generic_args
)
193 fn visit_generic_arg(&mut self, generic_arg
: &'ast GenericArg
) {
194 walk_generic_arg(self, generic_arg
)
196 fn visit_assoc_ty_constraint(&mut self, constraint
: &'ast AssocTyConstraint
) {
197 walk_assoc_ty_constraint(self, constraint
)
199 fn visit_attribute(&mut self, attr
: &'ast Attribute
) {
200 walk_attribute(self, attr
)
202 fn visit_vis(&mut self, vis
: &'ast Visibility
) {
205 fn visit_fn_ret_ty(&mut self, ret_ty
: &'ast FnRetTy
) {
206 walk_fn_ret_ty(self, ret_ty
)
208 fn visit_fn_header(&mut self, _header
: &'ast FnHeader
) {
211 fn visit_expr_field(&mut self, f
: &'ast ExprField
) {
212 walk_expr_field(self, f
)
214 fn visit_pat_field(&mut self, fp
: &'ast PatField
) {
215 walk_pat_field(self, fp
)
220 macro_rules
! walk_list
{
221 ($visitor
: expr
, $method
: ident
, $list
: expr
) => {
223 $visitor
.$
method(elem
)
226 ($visitor
: expr
, $method
: ident
, $list
: expr
, $
($extra_args
: expr
),*) => {
228 $visitor
.$
method(elem
, $
($extra_args
,)*)
233 pub fn walk_ident
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, ident
: Ident
) {
234 visitor
.visit_name(ident
.span
, ident
.name
);
237 pub fn walk_crate
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, krate
: &'a Crate
) {
238 walk_list
!(visitor
, visit_item
, &krate
.items
);
239 walk_list
!(visitor
, visit_attribute
, &krate
.attrs
);
242 pub fn walk_local
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, local
: &'a Local
) {
243 for attr
in local
.attrs
.iter() {
244 visitor
.visit_attribute(attr
);
246 visitor
.visit_pat(&local
.pat
);
247 walk_list
!(visitor
, visit_ty
, &local
.ty
);
248 walk_list
!(visitor
, visit_expr
, &local
.init
);
251 pub fn walk_label
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, label
: &'a Label
) {
252 visitor
.visit_ident(label
.ident
);
255 pub fn walk_lifetime
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, lifetime
: &'a Lifetime
) {
256 visitor
.visit_ident(lifetime
.ident
);
259 pub fn walk_poly_trait_ref
<'a
, V
>(
261 trait_ref
: &'a PolyTraitRef
,
262 _
: &TraitBoundModifier
,
266 walk_list
!(visitor
, visit_generic_param
, &trait_ref
.bound_generic_params
);
267 visitor
.visit_trait_ref(&trait_ref
.trait_ref
);
270 pub fn walk_trait_ref
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, trait_ref
: &'a TraitRef
) {
271 visitor
.visit_path(&trait_ref
.path
, trait_ref
.ref_id
)
274 pub fn walk_item
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, item
: &'a Item
) {
275 visitor
.visit_vis(&item
.vis
);
276 visitor
.visit_ident(item
.ident
);
278 ItemKind
::ExternCrate(orig_name
) => {
279 if let Some(orig_name
) = orig_name
{
280 visitor
.visit_name(item
.span
, orig_name
);
283 ItemKind
::Use(ref use_tree
) => visitor
.visit_use_tree(use_tree
, item
.id
, false),
284 ItemKind
::Static(ref typ
, _
, ref expr
) | ItemKind
::Const(_
, ref typ
, ref expr
) => {
285 visitor
.visit_ty(typ
);
286 walk_list
!(visitor
, visit_expr
, expr
);
288 ItemKind
::Fn(box FnKind(_
, ref sig
, ref generics
, ref body
)) => {
289 visitor
.visit_generics(generics
);
290 let kind
= FnKind
::Fn(FnCtxt
::Free
, item
.ident
, sig
, &item
.vis
, body
.as_deref());
291 visitor
.visit_fn(kind
, item
.span
, item
.id
)
293 ItemKind
::Mod(_unsafety
, ref mod_kind
) => match mod_kind
{
294 ModKind
::Loaded(items
, _inline
, _inner_span
) => {
295 walk_list
!(visitor
, visit_item
, items
)
297 ModKind
::Unloaded
=> {}
299 ItemKind
::ForeignMod(ref foreign_module
) => {
300 walk_list
!(visitor
, visit_foreign_item
, &foreign_module
.items
);
302 ItemKind
::GlobalAsm(ref ga
) => visitor
.visit_global_asm(ga
),
303 ItemKind
::TyAlias(box TyAliasKind(_
, ref generics
, ref bounds
, ref ty
)) => {
304 visitor
.visit_generics(generics
);
305 walk_list
!(visitor
, visit_param_bound
, bounds
);
306 walk_list
!(visitor
, visit_ty
, ty
);
308 ItemKind
::Enum(ref enum_definition
, ref generics
) => {
309 visitor
.visit_generics(generics
);
310 visitor
.visit_enum_def(enum_definition
, generics
, item
.id
, item
.span
)
312 ItemKind
::Impl(box ImplKind
{
322 visitor
.visit_generics(generics
);
323 walk_list
!(visitor
, visit_trait_ref
, of_trait
);
324 visitor
.visit_ty(self_ty
);
325 walk_list
!(visitor
, visit_assoc_item
, items
, AssocCtxt
::Impl
);
327 ItemKind
::Struct(ref struct_definition
, ref generics
)
328 | ItemKind
::Union(ref struct_definition
, ref generics
) => {
329 visitor
.visit_generics(generics
);
330 visitor
.visit_variant_data(struct_definition
);
332 ItemKind
::Trait(box TraitKind(.., ref generics
, ref bounds
, ref items
)) => {
333 visitor
.visit_generics(generics
);
334 walk_list
!(visitor
, visit_param_bound
, bounds
);
335 walk_list
!(visitor
, visit_assoc_item
, items
, AssocCtxt
::Trait
);
337 ItemKind
::TraitAlias(ref generics
, ref bounds
) => {
338 visitor
.visit_generics(generics
);
339 walk_list
!(visitor
, visit_param_bound
, bounds
);
341 ItemKind
::MacCall(ref mac
) => visitor
.visit_mac_call(mac
),
342 ItemKind
::MacroDef(ref ts
) => visitor
.visit_mac_def(ts
, item
.id
),
344 walk_list
!(visitor
, visit_attribute
, &item
.attrs
);
347 pub fn walk_enum_def
<'a
, V
: Visitor
<'a
>>(
349 enum_definition
: &'a EnumDef
,
353 walk_list
!(visitor
, visit_variant
, &enum_definition
.variants
);
356 pub fn walk_variant
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, variant
: &'a Variant
)
360 visitor
.visit_ident(variant
.ident
);
361 visitor
.visit_vis(&variant
.vis
);
362 visitor
.visit_variant_data(&variant
.data
);
363 walk_list
!(visitor
, visit_anon_const
, &variant
.disr_expr
);
364 walk_list
!(visitor
, visit_attribute
, &variant
.attrs
);
367 pub fn walk_expr_field
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, f
: &'a ExprField
) {
368 visitor
.visit_expr(&f
.expr
);
369 visitor
.visit_ident(f
.ident
);
370 walk_list
!(visitor
, visit_attribute
, f
.attrs
.iter());
373 pub fn walk_pat_field
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, fp
: &'a PatField
) {
374 visitor
.visit_ident(fp
.ident
);
375 visitor
.visit_pat(&fp
.pat
);
376 walk_list
!(visitor
, visit_attribute
, fp
.attrs
.iter());
379 pub fn walk_ty
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, typ
: &'a Ty
) {
381 TyKind
::Slice(ref ty
) | TyKind
::Paren(ref ty
) => visitor
.visit_ty(ty
),
382 TyKind
::Ptr(ref mutable_type
) => visitor
.visit_ty(&mutable_type
.ty
),
383 TyKind
::Rptr(ref opt_lifetime
, ref mutable_type
) => {
384 walk_list
!(visitor
, visit_lifetime
, opt_lifetime
);
385 visitor
.visit_ty(&mutable_type
.ty
)
387 TyKind
::Tup(ref tuple_element_types
) => {
388 walk_list
!(visitor
, visit_ty
, tuple_element_types
);
390 TyKind
::BareFn(ref function_declaration
) => {
391 walk_list
!(visitor
, visit_generic_param
, &function_declaration
.generic_params
);
392 walk_fn_decl(visitor
, &function_declaration
.decl
);
394 TyKind
::Path(ref maybe_qself
, ref path
) => {
395 if let Some(ref qself
) = *maybe_qself
{
396 visitor
.visit_ty(&qself
.ty
);
398 visitor
.visit_path(path
, typ
.id
);
400 TyKind
::Array(ref ty
, ref length
) => {
401 visitor
.visit_ty(ty
);
402 visitor
.visit_anon_const(length
)
404 TyKind
::TraitObject(ref bounds
, ..) | TyKind
::ImplTrait(_
, ref bounds
) => {
405 walk_list
!(visitor
, visit_param_bound
, bounds
);
407 TyKind
::Typeof(ref expression
) => visitor
.visit_anon_const(expression
),
408 TyKind
::Infer
| TyKind
::ImplicitSelf
| TyKind
::Err
=> {}
409 TyKind
::MacCall(ref mac
) => visitor
.visit_mac_call(mac
),
410 TyKind
::Never
| TyKind
::CVarArgs
=> {}
414 pub fn walk_path
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, path
: &'a Path
) {
415 for segment
in &path
.segments
{
416 visitor
.visit_path_segment(path
.span
, segment
);
420 pub fn walk_use_tree
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, use_tree
: &'a UseTree
, id
: NodeId
) {
421 visitor
.visit_path(&use_tree
.prefix
, id
);
422 match use_tree
.kind
{
423 UseTreeKind
::Simple(rename
, ..) => {
424 // The extra IDs are handled during HIR lowering.
425 if let Some(rename
) = rename
{
426 visitor
.visit_ident(rename
);
429 UseTreeKind
::Glob
=> {}
430 UseTreeKind
::Nested(ref use_trees
) => {
431 for &(ref nested_tree
, nested_id
) in use_trees
{
432 visitor
.visit_use_tree(nested_tree
, nested_id
, true);
438 pub fn walk_path_segment
<'a
, V
: Visitor
<'a
>>(
441 segment
: &'a PathSegment
,
443 visitor
.visit_ident(segment
.ident
);
444 if let Some(ref args
) = segment
.args
{
445 visitor
.visit_generic_args(path_span
, args
);
449 pub fn walk_generic_args
<'a
, V
>(visitor
: &mut V
, _path_span
: Span
, generic_args
: &'a GenericArgs
)
453 match *generic_args
{
454 GenericArgs
::AngleBracketed(ref data
) => {
455 for arg
in &data
.args
{
457 AngleBracketedArg
::Arg(a
) => visitor
.visit_generic_arg(a
),
458 AngleBracketedArg
::Constraint(c
) => visitor
.visit_assoc_ty_constraint(c
),
462 GenericArgs
::Parenthesized(ref data
) => {
463 walk_list
!(visitor
, visit_ty
, &data
.inputs
);
464 walk_fn_ret_ty(visitor
, &data
.output
);
469 pub fn walk_generic_arg
<'a
, V
>(visitor
: &mut V
, generic_arg
: &'a GenericArg
)
474 GenericArg
::Lifetime(lt
) => visitor
.visit_lifetime(lt
),
475 GenericArg
::Type(ty
) => visitor
.visit_ty(ty
),
476 GenericArg
::Const(ct
) => visitor
.visit_anon_const(ct
),
480 pub fn walk_assoc_ty_constraint
<'a
, V
: Visitor
<'a
>>(
482 constraint
: &'a AssocTyConstraint
,
484 visitor
.visit_ident(constraint
.ident
);
485 if let Some(ref gen_args
) = constraint
.gen_args
{
486 visitor
.visit_generic_args(gen_args
.span(), gen_args
);
488 match constraint
.kind
{
489 AssocTyConstraintKind
::Equality { ref ty }
=> {
490 visitor
.visit_ty(ty
);
492 AssocTyConstraintKind
::Bound { ref bounds }
=> {
493 walk_list
!(visitor
, visit_param_bound
, bounds
);
498 pub fn walk_pat
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, pattern
: &'a Pat
) {
500 PatKind
::TupleStruct(ref path
, ref elems
) => {
501 visitor
.visit_path(path
, pattern
.id
);
502 walk_list
!(visitor
, visit_pat
, elems
);
504 PatKind
::Path(ref opt_qself
, ref path
) => {
505 if let Some(ref qself
) = *opt_qself
{
506 visitor
.visit_ty(&qself
.ty
);
508 visitor
.visit_path(path
, pattern
.id
)
510 PatKind
::Struct(ref path
, ref fields
, _
) => {
511 visitor
.visit_path(path
, pattern
.id
);
512 walk_list
!(visitor
, visit_pat_field
, fields
);
514 PatKind
::Box(ref subpattern
)
515 | PatKind
::Ref(ref subpattern
, _
)
516 | PatKind
::Paren(ref subpattern
) => visitor
.visit_pat(subpattern
),
517 PatKind
::Ident(_
, ident
, ref optional_subpattern
) => {
518 visitor
.visit_ident(ident
);
519 walk_list
!(visitor
, visit_pat
, optional_subpattern
);
521 PatKind
::Lit(ref expression
) => visitor
.visit_expr(expression
),
522 PatKind
::Range(ref lower_bound
, ref upper_bound
, _
) => {
523 walk_list
!(visitor
, visit_expr
, lower_bound
);
524 walk_list
!(visitor
, visit_expr
, upper_bound
);
526 PatKind
::Wild
| PatKind
::Rest
=> {}
527 PatKind
::Tuple(ref elems
) | PatKind
::Slice(ref elems
) | PatKind
::Or(ref elems
) => {
528 walk_list
!(visitor
, visit_pat
, elems
);
530 PatKind
::MacCall(ref mac
) => visitor
.visit_mac_call(mac
),
534 pub fn walk_foreign_item
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, item
: &'a ForeignItem
) {
535 let Item { id, span, ident, ref vis, ref attrs, ref kind, tokens: _ }
= *item
;
536 visitor
.visit_vis(vis
);
537 visitor
.visit_ident(ident
);
538 walk_list
!(visitor
, visit_attribute
, attrs
);
540 ForeignItemKind
::Static(ty
, _
, expr
) => {
541 visitor
.visit_ty(ty
);
542 walk_list
!(visitor
, visit_expr
, expr
);
544 ForeignItemKind
::Fn(box FnKind(_
, sig
, generics
, body
)) => {
545 visitor
.visit_generics(generics
);
546 let kind
= FnKind
::Fn(FnCtxt
::Foreign
, ident
, sig
, vis
, body
.as_deref());
547 visitor
.visit_fn(kind
, span
, id
);
549 ForeignItemKind
::TyAlias(box TyAliasKind(_
, generics
, bounds
, ty
)) => {
550 visitor
.visit_generics(generics
);
551 walk_list
!(visitor
, visit_param_bound
, bounds
);
552 walk_list
!(visitor
, visit_ty
, ty
);
554 ForeignItemKind
::MacCall(mac
) => {
555 visitor
.visit_mac_call(mac
);
560 pub fn walk_global_asm
<'a
, V
: Visitor
<'a
>>(_
: &mut V
, _
: &'a GlobalAsm
) {
564 pub fn walk_param_bound
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, bound
: &'a GenericBound
) {
566 GenericBound
::Trait(ref typ
, ref modifier
) => visitor
.visit_poly_trait_ref(typ
, modifier
),
567 GenericBound
::Outlives(ref lifetime
) => visitor
.visit_lifetime(lifetime
),
571 pub fn walk_generic_param
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, param
: &'a GenericParam
) {
572 visitor
.visit_ident(param
.ident
);
573 walk_list
!(visitor
, visit_attribute
, param
.attrs
.iter());
574 walk_list
!(visitor
, visit_param_bound
, ¶m
.bounds
);
576 GenericParamKind
::Lifetime
=> (),
577 GenericParamKind
::Type { ref default }
=> walk_list
!(visitor
, visit_ty
, default),
578 GenericParamKind
::Const { ref ty, ref default, .. }
=> {
579 visitor
.visit_ty(ty
);
580 if let Some(default) = default {
581 visitor
.visit_anon_const(default);
587 pub fn walk_generics
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, generics
: &'a Generics
) {
588 walk_list
!(visitor
, visit_generic_param
, &generics
.params
);
589 walk_list
!(visitor
, visit_where_predicate
, &generics
.where_clause
.predicates
);
592 pub fn walk_where_predicate
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, predicate
: &'a WherePredicate
) {
594 WherePredicate
::BoundPredicate(WhereBoundPredicate
{
597 ref bound_generic_params
,
600 visitor
.visit_ty(bounded_ty
);
601 walk_list
!(visitor
, visit_param_bound
, bounds
);
602 walk_list
!(visitor
, visit_generic_param
, bound_generic_params
);
604 WherePredicate
::RegionPredicate(WhereRegionPredicate
{
605 ref lifetime
, ref bounds
, ..
607 visitor
.visit_lifetime(lifetime
);
608 walk_list
!(visitor
, visit_param_bound
, bounds
);
610 WherePredicate
::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty, .. }
) => {
611 visitor
.visit_ty(lhs_ty
);
612 visitor
.visit_ty(rhs_ty
);
617 pub fn walk_fn_ret_ty
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, ret_ty
: &'a FnRetTy
) {
618 if let FnRetTy
::Ty(ref output_ty
) = *ret_ty
{
619 visitor
.visit_ty(output_ty
)
623 pub fn walk_fn_decl
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, function_declaration
: &'a FnDecl
) {
624 for param
in &function_declaration
.inputs
{
625 visitor
.visit_param(param
);
627 visitor
.visit_fn_ret_ty(&function_declaration
.output
);
630 pub fn walk_fn
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, kind
: FnKind
<'a
>, _span
: Span
) {
632 FnKind
::Fn(_
, _
, sig
, _
, body
) => {
633 visitor
.visit_fn_header(&sig
.header
);
634 walk_fn_decl(visitor
, &sig
.decl
);
635 walk_list
!(visitor
, visit_block
, body
);
637 FnKind
::Closure(decl
, body
) => {
638 walk_fn_decl(visitor
, decl
);
639 visitor
.visit_expr(body
);
644 pub fn walk_assoc_item
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, item
: &'a AssocItem
, ctxt
: AssocCtxt
) {
645 let Item { id, span, ident, ref vis, ref attrs, ref kind, tokens: _ }
= *item
;
646 visitor
.visit_vis(vis
);
647 visitor
.visit_ident(ident
);
648 walk_list
!(visitor
, visit_attribute
, attrs
);
650 AssocItemKind
::Const(_
, ty
, expr
) => {
651 visitor
.visit_ty(ty
);
652 walk_list
!(visitor
, visit_expr
, expr
);
654 AssocItemKind
::Fn(box FnKind(_
, sig
, generics
, body
)) => {
655 visitor
.visit_generics(generics
);
656 let kind
= FnKind
::Fn(FnCtxt
::Assoc(ctxt
), ident
, sig
, vis
, body
.as_deref());
657 visitor
.visit_fn(kind
, span
, id
);
659 AssocItemKind
::TyAlias(box TyAliasKind(_
, generics
, bounds
, ty
)) => {
660 visitor
.visit_generics(generics
);
661 walk_list
!(visitor
, visit_param_bound
, bounds
);
662 walk_list
!(visitor
, visit_ty
, ty
);
664 AssocItemKind
::MacCall(mac
) => {
665 visitor
.visit_mac_call(mac
);
670 pub fn walk_struct_def
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, struct_definition
: &'a VariantData
) {
671 walk_list
!(visitor
, visit_field_def
, struct_definition
.fields());
674 pub fn walk_field_def
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, field
: &'a FieldDef
) {
675 visitor
.visit_vis(&field
.vis
);
676 if let Some(ident
) = field
.ident
{
677 visitor
.visit_ident(ident
);
679 visitor
.visit_ty(&field
.ty
);
680 walk_list
!(visitor
, visit_attribute
, &field
.attrs
);
683 pub fn walk_block
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, block
: &'a Block
) {
684 walk_list
!(visitor
, visit_stmt
, &block
.stmts
);
687 pub fn walk_stmt
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, statement
: &'a Stmt
) {
688 match statement
.kind
{
689 StmtKind
::Local(ref local
) => visitor
.visit_local(local
),
690 StmtKind
::Item(ref item
) => visitor
.visit_item(item
),
691 StmtKind
::Expr(ref expr
) | StmtKind
::Semi(ref expr
) => visitor
.visit_expr(expr
),
692 StmtKind
::Empty
=> {}
693 StmtKind
::MacCall(ref mac
) => {
694 let MacCallStmt { ref mac, style: _, ref attrs, tokens: _ }
= **mac
;
695 visitor
.visit_mac_call(mac
);
696 for attr
in attrs
.iter() {
697 visitor
.visit_attribute(attr
);
703 pub fn walk_mac
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, mac
: &'a MacCall
) {
704 visitor
.visit_path(&mac
.path
, DUMMY_NODE_ID
);
707 pub fn walk_anon_const
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, constant
: &'a AnonConst
) {
708 visitor
.visit_expr(&constant
.value
);
711 pub fn walk_expr
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, expression
: &'a Expr
) {
712 walk_list
!(visitor
, visit_attribute
, expression
.attrs
.iter());
714 match expression
.kind
{
715 ExprKind
::Box(ref subexpression
) => visitor
.visit_expr(subexpression
),
716 ExprKind
::Array(ref subexpressions
) => {
717 walk_list
!(visitor
, visit_expr
, subexpressions
);
719 ExprKind
::ConstBlock(ref anon_const
) => visitor
.visit_anon_const(anon_const
),
720 ExprKind
::Repeat(ref element
, ref count
) => {
721 visitor
.visit_expr(element
);
722 visitor
.visit_anon_const(count
)
724 ExprKind
::Struct(ref se
) => {
725 visitor
.visit_path(&se
.path
, expression
.id
);
726 walk_list
!(visitor
, visit_expr_field
, &se
.fields
);
728 StructRest
::Base(expr
) => visitor
.visit_expr(expr
),
729 StructRest
::Rest(_span
) => {}
730 StructRest
::None
=> {}
733 ExprKind
::Tup(ref subexpressions
) => {
734 walk_list
!(visitor
, visit_expr
, subexpressions
);
736 ExprKind
::Call(ref callee_expression
, ref arguments
) => {
737 visitor
.visit_expr(callee_expression
);
738 walk_list
!(visitor
, visit_expr
, arguments
);
740 ExprKind
::MethodCall(ref segment
, ref arguments
, _span
) => {
741 visitor
.visit_path_segment(expression
.span
, segment
);
742 walk_list
!(visitor
, visit_expr
, arguments
);
744 ExprKind
::Binary(_
, ref left_expression
, ref right_expression
) => {
745 visitor
.visit_expr(left_expression
);
746 visitor
.visit_expr(right_expression
)
748 ExprKind
::AddrOf(_
, _
, ref subexpression
) | ExprKind
::Unary(_
, ref subexpression
) => {
749 visitor
.visit_expr(subexpression
)
751 ExprKind
::Cast(ref subexpression
, ref typ
) | ExprKind
::Type(ref subexpression
, ref typ
) => {
752 visitor
.visit_expr(subexpression
);
753 visitor
.visit_ty(typ
)
755 ExprKind
::Let(ref pat
, ref scrutinee
) => {
756 visitor
.visit_pat(pat
);
757 visitor
.visit_expr(scrutinee
);
759 ExprKind
::If(ref head_expression
, ref if_block
, ref optional_else
) => {
760 visitor
.visit_expr(head_expression
);
761 visitor
.visit_block(if_block
);
762 walk_list
!(visitor
, visit_expr
, optional_else
);
764 ExprKind
::While(ref subexpression
, ref block
, ref opt_label
) => {
765 walk_list
!(visitor
, visit_label
, opt_label
);
766 visitor
.visit_expr(subexpression
);
767 visitor
.visit_block(block
);
769 ExprKind
::ForLoop(ref pattern
, ref subexpression
, ref block
, ref opt_label
) => {
770 walk_list
!(visitor
, visit_label
, opt_label
);
771 visitor
.visit_pat(pattern
);
772 visitor
.visit_expr(subexpression
);
773 visitor
.visit_block(block
);
775 ExprKind
::Loop(ref block
, ref opt_label
) => {
776 walk_list
!(visitor
, visit_label
, opt_label
);
777 visitor
.visit_block(block
);
779 ExprKind
::Match(ref subexpression
, ref arms
) => {
780 visitor
.visit_expr(subexpression
);
781 walk_list
!(visitor
, visit_arm
, arms
);
783 ExprKind
::Closure(_
, _
, _
, ref decl
, ref body
, _decl_span
) => {
784 visitor
.visit_fn(FnKind
::Closure(decl
, body
), expression
.span
, expression
.id
)
786 ExprKind
::Block(ref block
, ref opt_label
) => {
787 walk_list
!(visitor
, visit_label
, opt_label
);
788 visitor
.visit_block(block
);
790 ExprKind
::Async(_
, _
, ref body
) => {
791 visitor
.visit_block(body
);
793 ExprKind
::Await(ref expr
) => visitor
.visit_expr(expr
),
794 ExprKind
::Assign(ref lhs
, ref rhs
, _
) => {
795 visitor
.visit_expr(lhs
);
796 visitor
.visit_expr(rhs
);
798 ExprKind
::AssignOp(_
, ref left_expression
, ref right_expression
) => {
799 visitor
.visit_expr(left_expression
);
800 visitor
.visit_expr(right_expression
);
802 ExprKind
::Field(ref subexpression
, ident
) => {
803 visitor
.visit_expr(subexpression
);
804 visitor
.visit_ident(ident
);
806 ExprKind
::Index(ref main_expression
, ref index_expression
) => {
807 visitor
.visit_expr(main_expression
);
808 visitor
.visit_expr(index_expression
)
810 ExprKind
::Range(ref start
, ref end
, _
) => {
811 walk_list
!(visitor
, visit_expr
, start
);
812 walk_list
!(visitor
, visit_expr
, end
);
814 ExprKind
::Underscore
=> {}
815 ExprKind
::Path(ref maybe_qself
, ref path
) => {
816 if let Some(ref qself
) = *maybe_qself
{
817 visitor
.visit_ty(&qself
.ty
);
819 visitor
.visit_path(path
, expression
.id
)
821 ExprKind
::Break(ref opt_label
, ref opt_expr
) => {
822 walk_list
!(visitor
, visit_label
, opt_label
);
823 walk_list
!(visitor
, visit_expr
, opt_expr
);
825 ExprKind
::Continue(ref opt_label
) => {
826 walk_list
!(visitor
, visit_label
, opt_label
);
828 ExprKind
::Ret(ref optional_expression
) => {
829 walk_list
!(visitor
, visit_expr
, optional_expression
);
831 ExprKind
::MacCall(ref mac
) => visitor
.visit_mac_call(mac
),
832 ExprKind
::Paren(ref subexpression
) => visitor
.visit_expr(subexpression
),
833 ExprKind
::InlineAsm(ref ia
) => {
834 for (op
, _
) in &ia
.operands
{
836 InlineAsmOperand
::In { expr, .. }
837 | InlineAsmOperand
::InOut { expr, .. }
838 | InlineAsmOperand
::Const { expr, .. }
839 | InlineAsmOperand
::Sym { expr, .. }
=> visitor
.visit_expr(expr
),
840 InlineAsmOperand
::Out { expr, .. }
=> {
841 if let Some(expr
) = expr
{
842 visitor
.visit_expr(expr
);
845 InlineAsmOperand
::SplitInOut { in_expr, out_expr, .. }
=> {
846 visitor
.visit_expr(in_expr
);
847 if let Some(out_expr
) = out_expr
{
848 visitor
.visit_expr(out_expr
);
854 ExprKind
::LlvmInlineAsm(ref ia
) => {
855 for &(_
, ref input
) in &ia
.inputs
{
856 visitor
.visit_expr(input
)
858 for output
in &ia
.outputs
{
859 visitor
.visit_expr(&output
.expr
)
862 ExprKind
::Yield(ref optional_expression
) => {
863 walk_list
!(visitor
, visit_expr
, optional_expression
);
865 ExprKind
::Try(ref subexpression
) => visitor
.visit_expr(subexpression
),
866 ExprKind
::TryBlock(ref body
) => visitor
.visit_block(body
),
867 ExprKind
::Lit(_
) | ExprKind
::Err
=> {}
870 visitor
.visit_expr_post(expression
)
873 pub fn walk_param
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, param
: &'a Param
) {
874 walk_list
!(visitor
, visit_attribute
, param
.attrs
.iter());
875 visitor
.visit_pat(¶m
.pat
);
876 visitor
.visit_ty(¶m
.ty
);
879 pub fn walk_arm
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, arm
: &'a Arm
) {
880 visitor
.visit_pat(&arm
.pat
);
881 walk_list
!(visitor
, visit_expr
, &arm
.guard
);
882 visitor
.visit_expr(&arm
.body
);
883 walk_list
!(visitor
, visit_attribute
, &arm
.attrs
);
886 pub fn walk_vis
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, vis
: &'a Visibility
) {
887 if let VisibilityKind
::Restricted { ref path, id }
= vis
.kind
{
888 visitor
.visit_path(path
, id
);
892 pub fn walk_attribute
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, attr
: &'a Attribute
) {
894 AttrKind
::Normal(ref item
, ref _tokens
) => walk_mac_args(visitor
, &item
.args
),
895 AttrKind
::DocComment(..) => {}
899 pub fn walk_mac_args
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, args
: &'a MacArgs
) {
902 MacArgs
::Delimited(_dspan
, _delim
, _tokens
) => {}
903 // The value in `#[key = VALUE]` must be visited as an expression for backward
904 // compatibility, so that macros can be expanded in that position.
905 MacArgs
::Eq(_eq_span
, token
) => match &token
.kind
{
906 token
::Interpolated(nt
) => match &**nt
{
907 token
::NtExpr(expr
) => visitor
.visit_expr(expr
),
908 t
=> panic
!("unexpected token in key-value attribute: {:?}", t
),
910 t
=> panic
!("unexpected token in key-value attribute: {:?}", t
),