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.
17 use crate::parse
::token
::Token
;
18 use crate::tokenstream
::{TokenTree, TokenStream}
;
22 #[derive(Copy, Clone)]
24 /// E.g., `fn foo()` or `extern "Abi" fn foo()`.
25 ItemFn(Ident
, &'a FnHeader
, &'a Visibility
, &'a Block
),
27 /// E.g., `fn foo(&self)`.
28 Method(Ident
, &'a MethodSig
, Option
<&'a Visibility
>, &'a Block
),
30 /// E.g., `|x, y| body`.
35 pub fn header(&self) -> Option
<&'a FnHeader
> {
37 FnKind
::ItemFn(_
, header
, _
, _
) => Some(header
),
38 FnKind
::Method(_
, sig
, _
, _
) => Some(&sig
.header
),
39 FnKind
::Closure(_
) => None
,
44 /// Each method of the `Visitor` trait is a hook to be potentially
45 /// overridden. Each method's default implementation recursively visits
46 /// the substructure of the input via the corresponding `walk` method;
47 /// e.g., the `visit_mod` method by default calls `visit::walk_mod`.
49 /// If you want to ensure that your code handles every variant
50 /// explicitly, you need to override each method. (And you also need
51 /// to monitor future changes to `Visitor` in case a new method with a
52 /// new default implementation gets introduced.)
53 pub trait Visitor
<'ast
>: Sized
{
54 fn visit_name(&mut self, _span
: Span
, _name
: Name
) {
57 fn visit_ident(&mut self, ident
: Ident
) {
58 walk_ident(self, ident
);
60 fn visit_mod(&mut self, m
: &'ast Mod
, _s
: Span
, _attrs
: &[Attribute
], _n
: NodeId
) {
63 fn visit_foreign_item(&mut self, i
: &'ast ForeignItem
) { walk_foreign_item(self, i) }
64 fn visit_global_asm(&mut self, ga
: &'ast GlobalAsm
) { walk_global_asm(self, ga) }
65 fn visit_item(&mut self, i
: &'ast Item
) { walk_item(self, i) }
66 fn visit_local(&mut self, l
: &'ast Local
) { walk_local(self, l) }
67 fn visit_block(&mut self, b
: &'ast Block
) { walk_block(self, b) }
68 fn visit_stmt(&mut self, s
: &'ast Stmt
) { walk_stmt(self, s) }
69 fn visit_param(&mut self, param
: &'ast Param
) { walk_param(self, param) }
70 fn visit_arm(&mut self, a
: &'ast Arm
) { walk_arm(self, a) }
71 fn visit_pat(&mut self, p
: &'ast Pat
) { walk_pat(self, p) }
72 fn visit_anon_const(&mut self, c
: &'ast AnonConst
) { walk_anon_const(self, c) }
73 fn visit_expr(&mut self, ex
: &'ast Expr
) { walk_expr(self, ex) }
74 fn visit_expr_post(&mut self, _ex
: &'ast Expr
) { }
75 fn visit_ty(&mut self, t
: &'ast Ty
) { walk_ty(self, t) }
76 fn visit_generic_param(&mut self, param
: &'ast GenericParam
) {
77 walk_generic_param(self, param
)
79 fn visit_generics(&mut self, g
: &'ast Generics
) { walk_generics(self, g) }
80 fn visit_where_predicate(&mut self, p
: &'ast WherePredicate
) {
81 walk_where_predicate(self, p
)
83 fn visit_fn(&mut self, fk
: FnKind
<'ast
>, fd
: &'ast FnDecl
, s
: Span
, _
: NodeId
) {
84 walk_fn(self, fk
, fd
, s
)
86 fn visit_trait_item(&mut self, ti
: &'ast TraitItem
) { walk_trait_item(self, ti) }
87 fn visit_impl_item(&mut self, ii
: &'ast ImplItem
) { walk_impl_item(self, ii) }
88 fn visit_trait_ref(&mut self, t
: &'ast TraitRef
) { walk_trait_ref(self, t) }
89 fn visit_param_bound(&mut self, bounds
: &'ast GenericBound
) {
90 walk_param_bound(self, bounds
)
92 fn visit_poly_trait_ref(&mut self, t
: &'ast PolyTraitRef
, m
: &'ast TraitBoundModifier
) {
93 walk_poly_trait_ref(self, t
, m
)
95 fn visit_variant_data(&mut self, s
: &'ast VariantData
) {
96 walk_struct_def(self, s
)
98 fn visit_struct_field(&mut self, s
: &'ast StructField
) { walk_struct_field(self, s) }
99 fn visit_enum_def(&mut self, enum_definition
: &'ast EnumDef
,
100 generics
: &'ast Generics
, item_id
: NodeId
, _
: Span
) {
101 walk_enum_def(self, enum_definition
, generics
, item_id
)
103 fn visit_variant(&mut self, v
: &'ast Variant
) {
104 walk_variant(self, v
)
106 fn visit_label(&mut self, label
: &'ast Label
) {
107 walk_label(self, label
)
109 fn visit_lifetime(&mut self, lifetime
: &'ast Lifetime
) {
110 walk_lifetime(self, lifetime
)
112 fn visit_mac(&mut self, _mac
: &'ast Mac
) {
113 panic
!("visit_mac disabled by default");
114 // N.B., see note about macros above.
115 // if you really want a visitor that
116 // works on macros, use this
117 // definition in your trait impl:
118 // visit::walk_mac(self, _mac)
120 fn visit_mac_def(&mut self, _mac
: &'ast MacroDef
, _id
: NodeId
) {
123 fn visit_path(&mut self, path
: &'ast Path
, _id
: NodeId
) {
124 walk_path(self, path
)
126 fn visit_use_tree(&mut self, use_tree
: &'ast UseTree
, id
: NodeId
, _nested
: bool
) {
127 walk_use_tree(self, use_tree
, id
)
129 fn visit_path_segment(&mut self, path_span
: Span
, path_segment
: &'ast PathSegment
) {
130 walk_path_segment(self, path_span
, path_segment
)
132 fn visit_generic_args(&mut self, path_span
: Span
, generic_args
: &'ast GenericArgs
) {
133 walk_generic_args(self, path_span
, generic_args
)
135 fn visit_generic_arg(&mut self, generic_arg
: &'ast GenericArg
) {
137 GenericArg
::Lifetime(lt
) => self.visit_lifetime(lt
),
138 GenericArg
::Type(ty
) => self.visit_ty(ty
),
139 GenericArg
::Const(ct
) => self.visit_anon_const(ct
),
142 fn visit_assoc_ty_constraint(&mut self, constraint
: &'ast AssocTyConstraint
) {
143 walk_assoc_ty_constraint(self, constraint
)
145 fn visit_attribute(&mut self, attr
: &'ast Attribute
) {
146 walk_attribute(self, attr
)
148 fn visit_tt(&mut self, tt
: TokenTree
) {
151 fn visit_tts(&mut self, tts
: TokenStream
) {
154 fn visit_token(&mut self, _t
: Token
) {}
155 // FIXME: add `visit_interpolated` and `walk_interpolated`
156 fn visit_vis(&mut self, vis
: &'ast Visibility
) {
159 fn visit_fn_ret_ty(&mut self, ret_ty
: &'ast FunctionRetTy
) {
160 walk_fn_ret_ty(self, ret_ty
)
162 fn visit_fn_header(&mut self, _header
: &'ast FnHeader
) {
165 fn visit_field(&mut self, f
: &'ast Field
) {
168 fn visit_field_pattern(&mut self, fp
: &'ast FieldPat
) {
169 walk_field_pattern(self, fp
)
174 macro_rules
! walk_list
{
175 ($visitor
: expr
, $method
: ident
, $list
: expr
) => {
177 $visitor
.$
method(elem
)
180 ($visitor
: expr
, $method
: ident
, $list
: expr
, $
($extra_args
: expr
),*) => {
182 $visitor
.$
method(elem
, $
($extra_args
,)*)
187 pub fn walk_ident
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, ident
: Ident
) {
188 visitor
.visit_name(ident
.span
, ident
.name
);
191 pub fn walk_crate
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, krate
: &'a Crate
) {
192 visitor
.visit_mod(&krate
.module
, krate
.span
, &krate
.attrs
, CRATE_NODE_ID
);
193 walk_list
!(visitor
, visit_attribute
, &krate
.attrs
);
196 pub fn walk_mod
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, module
: &'a Mod
) {
197 walk_list
!(visitor
, visit_item
, &module
.items
);
200 pub fn walk_local
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, local
: &'a Local
) {
201 for attr
in local
.attrs
.iter() {
202 visitor
.visit_attribute(attr
);
204 visitor
.visit_pat(&local
.pat
);
205 walk_list
!(visitor
, visit_ty
, &local
.ty
);
206 walk_list
!(visitor
, visit_expr
, &local
.init
);
209 pub fn walk_label
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, label
: &'a Label
) {
210 visitor
.visit_ident(label
.ident
);
213 pub fn walk_lifetime
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, lifetime
: &'a Lifetime
) {
214 visitor
.visit_ident(lifetime
.ident
);
217 pub fn walk_poly_trait_ref
<'a
, V
>(visitor
: &mut V
,
218 trait_ref
: &'a PolyTraitRef
,
219 _
: &TraitBoundModifier
)
220 where V
: Visitor
<'a
>,
222 walk_list
!(visitor
, visit_generic_param
, &trait_ref
.bound_generic_params
);
223 visitor
.visit_trait_ref(&trait_ref
.trait_ref
);
226 pub fn walk_trait_ref
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, trait_ref
: &'a TraitRef
) {
227 visitor
.visit_path(&trait_ref
.path
, trait_ref
.ref_id
)
230 pub fn walk_item
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, item
: &'a Item
) {
231 visitor
.visit_vis(&item
.vis
);
232 visitor
.visit_ident(item
.ident
);
234 ItemKind
::ExternCrate(orig_name
) => {
235 if let Some(orig_name
) = orig_name
{
236 visitor
.visit_name(item
.span
, orig_name
);
239 ItemKind
::Use(ref use_tree
) => {
240 visitor
.visit_use_tree(use_tree
, item
.id
, false)
242 ItemKind
::Static(ref typ
, _
, ref expr
) |
243 ItemKind
::Const(ref typ
, ref expr
) => {
244 visitor
.visit_ty(typ
);
245 visitor
.visit_expr(expr
);
247 ItemKind
::Fn(ref declaration
, ref header
, ref generics
, ref body
) => {
248 visitor
.visit_generics(generics
);
249 visitor
.visit_fn_header(header
);
250 visitor
.visit_fn(FnKind
::ItemFn(item
.ident
, header
,
256 ItemKind
::Mod(ref module
) => {
257 visitor
.visit_mod(module
, item
.span
, &item
.attrs
, item
.id
)
259 ItemKind
::ForeignMod(ref foreign_module
) => {
260 walk_list
!(visitor
, visit_foreign_item
, &foreign_module
.items
);
262 ItemKind
::GlobalAsm(ref ga
) => visitor
.visit_global_asm(ga
),
263 ItemKind
::TyAlias(ref typ
, ref generics
) => {
264 visitor
.visit_ty(typ
);
265 visitor
.visit_generics(generics
)
267 ItemKind
::OpaqueTy(ref bounds
, ref generics
) => {
268 walk_list
!(visitor
, visit_param_bound
, bounds
);
269 visitor
.visit_generics(generics
)
271 ItemKind
::Enum(ref enum_definition
, ref generics
) => {
272 visitor
.visit_generics(generics
);
273 visitor
.visit_enum_def(enum_definition
, generics
, item
.id
, item
.span
)
275 ItemKind
::Impl(_
, _
, _
,
277 ref opt_trait_reference
,
280 visitor
.visit_generics(generics
);
281 walk_list
!(visitor
, visit_trait_ref
, opt_trait_reference
);
282 visitor
.visit_ty(typ
);
283 walk_list
!(visitor
, visit_impl_item
, impl_items
);
285 ItemKind
::Struct(ref struct_definition
, ref generics
) |
286 ItemKind
::Union(ref struct_definition
, ref generics
) => {
287 visitor
.visit_generics(generics
);
288 visitor
.visit_variant_data(struct_definition
);
290 ItemKind
::Trait(.., ref generics
, ref bounds
, ref methods
) => {
291 visitor
.visit_generics(generics
);
292 walk_list
!(visitor
, visit_param_bound
, bounds
);
293 walk_list
!(visitor
, visit_trait_item
, methods
);
295 ItemKind
::TraitAlias(ref generics
, ref bounds
) => {
296 visitor
.visit_generics(generics
);
297 walk_list
!(visitor
, visit_param_bound
, bounds
);
299 ItemKind
::Mac(ref mac
) => visitor
.visit_mac(mac
),
300 ItemKind
::MacroDef(ref ts
) => visitor
.visit_mac_def(ts
, item
.id
),
302 walk_list
!(visitor
, visit_attribute
, &item
.attrs
);
305 pub fn walk_enum_def
<'a
, V
: Visitor
<'a
>>(
307 enum_definition
: &'a EnumDef
,
311 walk_list
!(visitor
, visit_variant
, &enum_definition
.variants
);
314 pub fn walk_variant
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, variant
: &'a Variant
)
315 where V
: Visitor
<'a
>,
317 visitor
.visit_ident(variant
.ident
);
318 visitor
.visit_variant_data(&variant
.data
);
319 walk_list
!(visitor
, visit_anon_const
, &variant
.disr_expr
);
320 walk_list
!(visitor
, visit_attribute
, &variant
.attrs
);
323 pub fn walk_field
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, f
: &'a Field
) {
324 visitor
.visit_expr(&f
.expr
);
325 visitor
.visit_ident(f
.ident
);
326 walk_list
!(visitor
, visit_attribute
, f
.attrs
.iter());
329 pub fn walk_field_pattern
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, fp
: &'a FieldPat
) {
330 visitor
.visit_ident(fp
.ident
);
331 visitor
.visit_pat(&fp
.pat
);
332 walk_list
!(visitor
, visit_attribute
, fp
.attrs
.iter());
335 pub fn walk_ty
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, typ
: &'a Ty
) {
337 TyKind
::Slice(ref ty
) | TyKind
::Paren(ref ty
) => {
340 TyKind
::Ptr(ref mutable_type
) => {
341 visitor
.visit_ty(&mutable_type
.ty
)
343 TyKind
::Rptr(ref opt_lifetime
, ref mutable_type
) => {
344 walk_list
!(visitor
, visit_lifetime
, opt_lifetime
);
345 visitor
.visit_ty(&mutable_type
.ty
)
347 TyKind
::Tup(ref tuple_element_types
) => {
348 walk_list
!(visitor
, visit_ty
, tuple_element_types
);
350 TyKind
::BareFn(ref function_declaration
) => {
351 walk_list
!(visitor
, visit_generic_param
, &function_declaration
.generic_params
);
352 walk_fn_decl(visitor
, &function_declaration
.decl
);
354 TyKind
::Path(ref maybe_qself
, ref path
) => {
355 if let Some(ref qself
) = *maybe_qself
{
356 visitor
.visit_ty(&qself
.ty
);
358 visitor
.visit_path(path
, typ
.id
);
360 TyKind
::Array(ref ty
, ref length
) => {
361 visitor
.visit_ty(ty
);
362 visitor
.visit_anon_const(length
)
364 TyKind
::TraitObject(ref bounds
, ..) |
365 TyKind
::ImplTrait(_
, ref bounds
) => {
366 walk_list
!(visitor
, visit_param_bound
, bounds
);
368 TyKind
::Typeof(ref expression
) => {
369 visitor
.visit_anon_const(expression
)
371 TyKind
::Infer
| TyKind
::ImplicitSelf
| TyKind
::Err
=> {}
372 TyKind
::Mac(ref mac
) => {
373 visitor
.visit_mac(mac
)
376 TyKind
::CVarArgs
=> {}
380 pub fn walk_path
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, path
: &'a Path
) {
381 for segment
in &path
.segments
{
382 visitor
.visit_path_segment(path
.span
, segment
);
386 pub fn walk_use_tree
<'a
, V
: Visitor
<'a
>>(
387 visitor
: &mut V
, use_tree
: &'a UseTree
, id
: NodeId
,
389 visitor
.visit_path(&use_tree
.prefix
, id
);
390 match use_tree
.kind
{
391 UseTreeKind
::Simple(rename
, ..) => {
392 // The extra IDs are handled during HIR lowering.
393 if let Some(rename
) = rename
{
394 visitor
.visit_ident(rename
);
397 UseTreeKind
::Glob
=> {}
,
398 UseTreeKind
::Nested(ref use_trees
) => {
399 for &(ref nested_tree
, nested_id
) in use_trees
{
400 visitor
.visit_use_tree(nested_tree
, nested_id
, true);
406 pub fn walk_path_segment
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
,
408 segment
: &'a PathSegment
) {
409 visitor
.visit_ident(segment
.ident
);
410 if let Some(ref args
) = segment
.args
{
411 visitor
.visit_generic_args(path_span
, args
);
415 pub fn walk_generic_args
<'a
, V
>(visitor
: &mut V
,
417 generic_args
: &'a GenericArgs
)
418 where V
: Visitor
<'a
>,
420 match *generic_args
{
421 GenericArgs
::AngleBracketed(ref data
) => {
422 walk_list
!(visitor
, visit_generic_arg
, &data
.args
);
423 walk_list
!(visitor
, visit_assoc_ty_constraint
, &data
.constraints
);
425 GenericArgs
::Parenthesized(ref data
) => {
426 walk_list
!(visitor
, visit_ty
, &data
.inputs
);
427 walk_list
!(visitor
, visit_ty
, &data
.output
);
432 pub fn walk_assoc_ty_constraint
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
,
433 constraint
: &'a AssocTyConstraint
) {
434 visitor
.visit_ident(constraint
.ident
);
435 match constraint
.kind
{
436 AssocTyConstraintKind
::Equality { ref ty }
=> {
437 visitor
.visit_ty(ty
);
439 AssocTyConstraintKind
::Bound { ref bounds }
=> {
440 walk_list
!(visitor
, visit_param_bound
, bounds
);
445 pub fn walk_pat
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, pattern
: &'a Pat
) {
447 PatKind
::TupleStruct(ref path
, ref elems
) => {
448 visitor
.visit_path(path
, pattern
.id
);
449 walk_list
!(visitor
, visit_pat
, elems
);
451 PatKind
::Path(ref opt_qself
, ref path
) => {
452 if let Some(ref qself
) = *opt_qself
{
453 visitor
.visit_ty(&qself
.ty
);
455 visitor
.visit_path(path
, pattern
.id
)
457 PatKind
::Struct(ref path
, ref fields
, _
) => {
458 visitor
.visit_path(path
, pattern
.id
);
459 walk_list
!(visitor
, visit_field_pattern
, fields
);
461 PatKind
::Box(ref subpattern
) |
462 PatKind
::Ref(ref subpattern
, _
) |
463 PatKind
::Paren(ref subpattern
) => {
464 visitor
.visit_pat(subpattern
)
466 PatKind
::Ident(_
, ident
, ref optional_subpattern
) => {
467 visitor
.visit_ident(ident
);
468 walk_list
!(visitor
, visit_pat
, optional_subpattern
);
470 PatKind
::Lit(ref expression
) => visitor
.visit_expr(expression
),
471 PatKind
::Range(ref lower_bound
, ref upper_bound
, _
) => {
472 visitor
.visit_expr(lower_bound
);
473 visitor
.visit_expr(upper_bound
);
475 PatKind
::Wild
| PatKind
::Rest
=> {}
,
476 PatKind
::Tuple(ref elems
)
477 | PatKind
::Slice(ref elems
)
478 | PatKind
::Or(ref elems
) => {
479 walk_list
!(visitor
, visit_pat
, elems
);
481 PatKind
::Mac(ref mac
) => visitor
.visit_mac(mac
),
485 pub fn walk_foreign_item
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, foreign_item
: &'a ForeignItem
) {
486 visitor
.visit_vis(&foreign_item
.vis
);
487 visitor
.visit_ident(foreign_item
.ident
);
489 match foreign_item
.node
{
490 ForeignItemKind
::Fn(ref function_declaration
, ref generics
) => {
491 walk_fn_decl(visitor
, function_declaration
);
492 visitor
.visit_generics(generics
)
494 ForeignItemKind
::Static(ref typ
, _
) => visitor
.visit_ty(typ
),
495 ForeignItemKind
::Ty
=> (),
496 ForeignItemKind
::Macro(ref mac
) => visitor
.visit_mac(mac
),
499 walk_list
!(visitor
, visit_attribute
, &foreign_item
.attrs
);
502 pub fn walk_global_asm
<'a
, V
: Visitor
<'a
>>(_
: &mut V
, _
: &'a GlobalAsm
) {
506 pub fn walk_param_bound
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, bound
: &'a GenericBound
) {
508 GenericBound
::Trait(ref typ
, ref modifier
) => visitor
.visit_poly_trait_ref(typ
, modifier
),
509 GenericBound
::Outlives(ref lifetime
) => visitor
.visit_lifetime(lifetime
),
513 pub fn walk_generic_param
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, param
: &'a GenericParam
) {
514 visitor
.visit_ident(param
.ident
);
515 walk_list
!(visitor
, visit_attribute
, param
.attrs
.iter());
516 walk_list
!(visitor
, visit_param_bound
, ¶m
.bounds
);
518 GenericParamKind
::Lifetime
=> (),
519 GenericParamKind
::Type { ref default }
=> walk_list
!(visitor
, visit_ty
, default),
520 GenericParamKind
::Const { ref ty, .. }
=> visitor
.visit_ty(ty
),
524 pub fn walk_generics
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, generics
: &'a Generics
) {
525 walk_list
!(visitor
, visit_generic_param
, &generics
.params
);
526 walk_list
!(visitor
, visit_where_predicate
, &generics
.where_clause
.predicates
);
529 pub fn walk_where_predicate
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, predicate
: &'a WherePredicate
) {
531 WherePredicate
::BoundPredicate(WhereBoundPredicate
{ref bounded_ty
,
533 ref bound_generic_params
,
535 visitor
.visit_ty(bounded_ty
);
536 walk_list
!(visitor
, visit_param_bound
, bounds
);
537 walk_list
!(visitor
, visit_generic_param
, bound_generic_params
);
539 WherePredicate
::RegionPredicate(WhereRegionPredicate
{ref lifetime
,
542 visitor
.visit_lifetime(lifetime
);
543 walk_list
!(visitor
, visit_param_bound
, bounds
);
545 WherePredicate
::EqPredicate(WhereEqPredicate
{ref lhs_ty
,
548 visitor
.visit_ty(lhs_ty
);
549 visitor
.visit_ty(rhs_ty
);
554 pub fn walk_fn_ret_ty
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, ret_ty
: &'a FunctionRetTy
) {
555 if let FunctionRetTy
::Ty(ref output_ty
) = *ret_ty
{
556 visitor
.visit_ty(output_ty
)
560 pub fn walk_fn_decl
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, function_declaration
: &'a FnDecl
) {
561 for param
in &function_declaration
.inputs
{
562 visitor
.visit_param(param
);
564 visitor
.visit_fn_ret_ty(&function_declaration
.output
);
567 pub fn walk_fn
<'a
, V
>(visitor
: &mut V
, kind
: FnKind
<'a
>, declaration
: &'a FnDecl
, _span
: Span
)
568 where V
: Visitor
<'a
>,
571 FnKind
::ItemFn(_
, header
, _
, body
) => {
572 visitor
.visit_fn_header(header
);
573 walk_fn_decl(visitor
, declaration
);
574 visitor
.visit_block(body
);
576 FnKind
::Method(_
, sig
, _
, body
) => {
577 visitor
.visit_fn_header(&sig
.header
);
578 walk_fn_decl(visitor
, declaration
);
579 visitor
.visit_block(body
);
581 FnKind
::Closure(body
) => {
582 walk_fn_decl(visitor
, declaration
);
583 visitor
.visit_expr(body
);
588 pub fn walk_trait_item
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, trait_item
: &'a TraitItem
) {
589 visitor
.visit_ident(trait_item
.ident
);
590 walk_list
!(visitor
, visit_attribute
, &trait_item
.attrs
);
591 visitor
.visit_generics(&trait_item
.generics
);
592 match trait_item
.node
{
593 TraitItemKind
::Const(ref ty
, ref default) => {
594 visitor
.visit_ty(ty
);
595 walk_list
!(visitor
, visit_expr
, default);
597 TraitItemKind
::Method(ref sig
, None
) => {
598 visitor
.visit_fn_header(&sig
.header
);
599 walk_fn_decl(visitor
, &sig
.decl
);
601 TraitItemKind
::Method(ref sig
, Some(ref body
)) => {
602 visitor
.visit_fn(FnKind
::Method(trait_item
.ident
, sig
, None
, body
),
603 &sig
.decl
, trait_item
.span
, trait_item
.id
);
605 TraitItemKind
::Type(ref bounds
, ref default) => {
606 walk_list
!(visitor
, visit_param_bound
, bounds
);
607 walk_list
!(visitor
, visit_ty
, default);
609 TraitItemKind
::Macro(ref mac
) => {
610 visitor
.visit_mac(mac
);
615 pub fn walk_impl_item
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, impl_item
: &'a ImplItem
) {
616 visitor
.visit_vis(&impl_item
.vis
);
617 visitor
.visit_ident(impl_item
.ident
);
618 walk_list
!(visitor
, visit_attribute
, &impl_item
.attrs
);
619 visitor
.visit_generics(&impl_item
.generics
);
620 match impl_item
.node
{
621 ImplItemKind
::Const(ref ty
, ref expr
) => {
622 visitor
.visit_ty(ty
);
623 visitor
.visit_expr(expr
);
625 ImplItemKind
::Method(ref sig
, ref body
) => {
626 visitor
.visit_fn(FnKind
::Method(impl_item
.ident
, sig
, Some(&impl_item
.vis
), body
),
627 &sig
.decl
, impl_item
.span
, impl_item
.id
);
629 ImplItemKind
::TyAlias(ref ty
) => {
630 visitor
.visit_ty(ty
);
632 ImplItemKind
::OpaqueTy(ref bounds
) => {
633 walk_list
!(visitor
, visit_param_bound
, bounds
);
635 ImplItemKind
::Macro(ref mac
) => {
636 visitor
.visit_mac(mac
);
641 pub fn walk_struct_def
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, struct_definition
: &'a VariantData
) {
642 walk_list
!(visitor
, visit_struct_field
, struct_definition
.fields());
645 pub fn walk_struct_field
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, struct_field
: &'a StructField
) {
646 visitor
.visit_vis(&struct_field
.vis
);
647 if let Some(ident
) = struct_field
.ident
{
648 visitor
.visit_ident(ident
);
650 visitor
.visit_ty(&struct_field
.ty
);
651 walk_list
!(visitor
, visit_attribute
, &struct_field
.attrs
);
654 pub fn walk_block
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, block
: &'a Block
) {
655 walk_list
!(visitor
, visit_stmt
, &block
.stmts
);
658 pub fn walk_stmt
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, statement
: &'a Stmt
) {
659 match statement
.node
{
660 StmtKind
::Local(ref local
) => visitor
.visit_local(local
),
661 StmtKind
::Item(ref item
) => visitor
.visit_item(item
),
662 StmtKind
::Expr(ref expression
) | StmtKind
::Semi(ref expression
) => {
663 visitor
.visit_expr(expression
)
665 StmtKind
::Mac(ref mac
) => {
666 let (ref mac
, _
, ref attrs
) = **mac
;
667 visitor
.visit_mac(mac
);
668 for attr
in attrs
.iter() {
669 visitor
.visit_attribute(attr
);
675 pub fn walk_mac
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, mac
: &'a Mac
) {
676 visitor
.visit_path(&mac
.path
, DUMMY_NODE_ID
);
679 pub fn walk_anon_const
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, constant
: &'a AnonConst
) {
680 visitor
.visit_expr(&constant
.value
);
683 pub fn walk_expr
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, expression
: &'a Expr
) {
684 walk_list
!(visitor
, visit_attribute
, expression
.attrs
.iter());
686 match expression
.node
{
687 ExprKind
::Box(ref subexpression
) => {
688 visitor
.visit_expr(subexpression
)
690 ExprKind
::Array(ref subexpressions
) => {
691 walk_list
!(visitor
, visit_expr
, subexpressions
);
693 ExprKind
::Repeat(ref element
, ref count
) => {
694 visitor
.visit_expr(element
);
695 visitor
.visit_anon_const(count
)
697 ExprKind
::Struct(ref path
, ref fields
, ref optional_base
) => {
698 visitor
.visit_path(path
, expression
.id
);
699 walk_list
!(visitor
, visit_field
, fields
);
700 walk_list
!(visitor
, visit_expr
, optional_base
);
702 ExprKind
::Tup(ref subexpressions
) => {
703 walk_list
!(visitor
, visit_expr
, subexpressions
);
705 ExprKind
::Call(ref callee_expression
, ref arguments
) => {
706 visitor
.visit_expr(callee_expression
);
707 walk_list
!(visitor
, visit_expr
, arguments
);
709 ExprKind
::MethodCall(ref segment
, ref arguments
) => {
710 visitor
.visit_path_segment(expression
.span
, segment
);
711 walk_list
!(visitor
, visit_expr
, arguments
);
713 ExprKind
::Binary(_
, ref left_expression
, ref right_expression
) => {
714 visitor
.visit_expr(left_expression
);
715 visitor
.visit_expr(right_expression
)
717 ExprKind
::AddrOf(_
, ref subexpression
) | ExprKind
::Unary(_
, ref subexpression
) => {
718 visitor
.visit_expr(subexpression
)
720 ExprKind
::Cast(ref subexpression
, ref typ
) | ExprKind
::Type(ref subexpression
, ref typ
) => {
721 visitor
.visit_expr(subexpression
);
722 visitor
.visit_ty(typ
)
724 ExprKind
::Let(ref pat
, ref scrutinee
) => {
725 visitor
.visit_pat(pat
);
726 visitor
.visit_expr(scrutinee
);
728 ExprKind
::If(ref head_expression
, ref if_block
, ref optional_else
) => {
729 visitor
.visit_expr(head_expression
);
730 visitor
.visit_block(if_block
);
731 walk_list
!(visitor
, visit_expr
, optional_else
);
733 ExprKind
::While(ref subexpression
, ref block
, ref opt_label
) => {
734 walk_list
!(visitor
, visit_label
, opt_label
);
735 visitor
.visit_expr(subexpression
);
736 visitor
.visit_block(block
);
738 ExprKind
::ForLoop(ref pattern
, ref subexpression
, ref block
, ref opt_label
) => {
739 walk_list
!(visitor
, visit_label
, opt_label
);
740 visitor
.visit_pat(pattern
);
741 visitor
.visit_expr(subexpression
);
742 visitor
.visit_block(block
);
744 ExprKind
::Loop(ref block
, ref opt_label
) => {
745 walk_list
!(visitor
, visit_label
, opt_label
);
746 visitor
.visit_block(block
);
748 ExprKind
::Match(ref subexpression
, ref arms
) => {
749 visitor
.visit_expr(subexpression
);
750 walk_list
!(visitor
, visit_arm
, arms
);
752 ExprKind
::Closure(_
, _
, _
, ref function_declaration
, ref body
, _decl_span
) => {
753 visitor
.visit_fn(FnKind
::Closure(body
),
754 function_declaration
,
758 ExprKind
::Block(ref block
, ref opt_label
) => {
759 walk_list
!(visitor
, visit_label
, opt_label
);
760 visitor
.visit_block(block
);
762 ExprKind
::Async(_
, _
, ref body
) => {
763 visitor
.visit_block(body
);
765 ExprKind
::Await(ref expr
) => visitor
.visit_expr(expr
),
766 ExprKind
::Assign(ref left_hand_expression
, ref right_hand_expression
) => {
767 visitor
.visit_expr(left_hand_expression
);
768 visitor
.visit_expr(right_hand_expression
);
770 ExprKind
::AssignOp(_
, ref left_expression
, ref right_expression
) => {
771 visitor
.visit_expr(left_expression
);
772 visitor
.visit_expr(right_expression
);
774 ExprKind
::Field(ref subexpression
, ident
) => {
775 visitor
.visit_expr(subexpression
);
776 visitor
.visit_ident(ident
);
778 ExprKind
::Index(ref main_expression
, ref index_expression
) => {
779 visitor
.visit_expr(main_expression
);
780 visitor
.visit_expr(index_expression
)
782 ExprKind
::Range(ref start
, ref end
, _
) => {
783 walk_list
!(visitor
, visit_expr
, start
);
784 walk_list
!(visitor
, visit_expr
, end
);
786 ExprKind
::Path(ref maybe_qself
, ref path
) => {
787 if let Some(ref qself
) = *maybe_qself
{
788 visitor
.visit_ty(&qself
.ty
);
790 visitor
.visit_path(path
, expression
.id
)
792 ExprKind
::Break(ref opt_label
, ref opt_expr
) => {
793 walk_list
!(visitor
, visit_label
, opt_label
);
794 walk_list
!(visitor
, visit_expr
, opt_expr
);
796 ExprKind
::Continue(ref opt_label
) => {
797 walk_list
!(visitor
, visit_label
, opt_label
);
799 ExprKind
::Ret(ref optional_expression
) => {
800 walk_list
!(visitor
, visit_expr
, optional_expression
);
802 ExprKind
::Mac(ref mac
) => visitor
.visit_mac(mac
),
803 ExprKind
::Paren(ref subexpression
) => {
804 visitor
.visit_expr(subexpression
)
806 ExprKind
::InlineAsm(ref ia
) => {
807 for &(_
, ref input
) in &ia
.inputs
{
808 visitor
.visit_expr(input
)
810 for output
in &ia
.outputs
{
811 visitor
.visit_expr(&output
.expr
)
814 ExprKind
::Yield(ref optional_expression
) => {
815 walk_list
!(visitor
, visit_expr
, optional_expression
);
817 ExprKind
::Try(ref subexpression
) => {
818 visitor
.visit_expr(subexpression
)
820 ExprKind
::TryBlock(ref body
) => {
821 visitor
.visit_block(body
)
823 ExprKind
::Lit(_
) | ExprKind
::Err
=> {}
826 visitor
.visit_expr_post(expression
)
829 pub fn walk_param
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, param
: &'a Param
) {
830 walk_list
!(visitor
, visit_attribute
, param
.attrs
.iter());
831 visitor
.visit_pat(¶m
.pat
);
832 visitor
.visit_ty(¶m
.ty
);
835 pub fn walk_arm
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, arm
: &'a Arm
) {
836 visitor
.visit_pat(&arm
.pat
);
837 // NOTE(or_patterns; Centril | dlrobertson):
838 // If you change this, also change the hack in `lowering.rs`.
839 walk_list
!(visitor
, visit_expr
, &arm
.guard
);
840 visitor
.visit_expr(&arm
.body
);
841 walk_list
!(visitor
, visit_attribute
, &arm
.attrs
);
844 pub fn walk_vis
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, vis
: &'a Visibility
) {
845 if let VisibilityKind
::Restricted { ref path, id }
= vis
.node
{
846 visitor
.visit_path(path
, id
);
850 pub fn walk_attribute
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, attr
: &'a Attribute
) {
851 visitor
.visit_tts(attr
.tokens
.clone());
854 pub fn walk_tt
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, tt
: TokenTree
) {
856 TokenTree
::Token(token
) => visitor
.visit_token(token
),
857 TokenTree
::Delimited(_
, _
, tts
) => visitor
.visit_tts(tts
),
861 pub fn walk_tts
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, tts
: TokenStream
) {
862 for tt
in tts
.trees() {
863 visitor
.visit_tt(tt
);