1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! AST walker. Each overridden visit method has full control over what
12 //! happens with its node, it can do its own traversal of the node's children,
13 //! call `visit::walk_*` to apply the default traversal algorithm, or prevent
14 //! deeper traversal by doing nothing.
16 //! Note: it is an important invariant that the default visitor walks the body
17 //! of a function in "execution order" (more concretely, reverse post-order
18 //! with respect to the CFG implied by the AST), meaning that if AST node A may
19 //! execute before AST node B, then A is visited first. The borrow checker in
20 //! particular relies on this property.
22 //! Note: walking an AST before macro expansion is probably a bad idea. For
23 //! instance, a walker looking for item names in a module will miss all of
24 //! those that are created by the expansion of a macro.
26 pub use self::FnKind
::*;
33 use owned_slice
::OwnedSlice
;
35 #[derive(Copy, Clone)]
37 /// fn foo() or extern "Abi" fn foo()
38 FkItemFn(Ident
, &'a Generics
, Unsafety
, Constness
, Abi
, Visibility
),
41 FkMethod(Ident
, &'a MethodSig
, Option
<Visibility
>),
48 /// Each method of the Visitor trait is a hook to be potentially
49 /// overridden. Each method's default implementation recursively visits
50 /// the substructure of the input via the corresponding `walk` method;
51 /// e.g. the `visit_mod` method by default calls `visit::walk_mod`.
53 /// If you want to ensure that your code handles every variant
54 /// explicitly, you need to override each method. (And you also need
55 /// to monitor future changes to `Visitor` in case a new method with a
56 /// new default implementation gets introduced.)
57 pub trait Visitor
<'v
> : Sized
{
58 fn visit_name(&mut self, _span
: Span
, _name
: Name
) {
61 fn visit_ident(&mut self, span
: Span
, ident
: Ident
) {
62 self.visit_name(span
, ident
.name
);
64 fn visit_mod(&mut self, m
: &'v Mod
, _s
: Span
, _n
: NodeId
) { walk_mod(self, m) }
65 fn visit_foreign_item(&mut self, i
: &'v ForeignItem
) { walk_foreign_item(self, i) }
66 fn visit_item(&mut self, i
: &'v Item
) { walk_item(self, i) }
67 fn visit_local(&mut self, l
: &'v Local
) { walk_local(self, l) }
68 fn visit_block(&mut self, b
: &'v Block
) { walk_block(self, b) }
69 fn visit_stmt(&mut self, s
: &'v Stmt
) { walk_stmt(self, s) }
70 fn visit_arm(&mut self, a
: &'v Arm
) { walk_arm(self, a) }
71 fn visit_pat(&mut self, p
: &'v Pat
) { walk_pat(self, p) }
72 fn visit_decl(&mut self, d
: &'v Decl
) { walk_decl(self, d) }
73 fn visit_expr(&mut self, ex
: &'v Expr
) { walk_expr(self, ex) }
74 fn visit_expr_post(&mut self, _ex
: &'v Expr
) { }
75 fn visit_ty(&mut self, t
: &'v Ty
) { walk_ty(self, t) }
76 fn visit_generics(&mut self, g
: &'v Generics
) { walk_generics(self, g) }
77 fn visit_fn(&mut self, fk
: FnKind
<'v
>, fd
: &'v FnDecl
, b
: &'v Block
, s
: Span
, _
: NodeId
) {
78 walk_fn(self, fk
, fd
, b
, s
)
80 fn visit_trait_item(&mut self, ti
: &'v TraitItem
) { walk_trait_item(self, ti) }
81 fn visit_impl_item(&mut self, ii
: &'v ImplItem
) { walk_impl_item(self, ii) }
82 fn visit_trait_ref(&mut self, t
: &'v TraitRef
) { walk_trait_ref(self, t) }
83 fn visit_ty_param_bound(&mut self, bounds
: &'v TyParamBound
) {
84 walk_ty_param_bound(self, bounds
)
86 fn visit_poly_trait_ref(&mut self, t
: &'v PolyTraitRef
, m
: &'v TraitBoundModifier
) {
87 walk_poly_trait_ref(self, t
, m
)
89 fn visit_struct_def(&mut self, s
: &'v StructDef
, _
: Ident
, _
: &'v Generics
, _
: NodeId
) {
90 walk_struct_def(self, s
)
92 fn visit_struct_field(&mut self, s
: &'v StructField
) { walk_struct_field(self, s) }
93 fn visit_variant(&mut self, v
: &'v Variant
, g
: &'v Generics
) { walk_variant(self, v, g) }
95 /// Visits an optional reference to a lifetime. The `span` is the span of some surrounding
96 /// reference should opt_lifetime be None.
97 fn visit_opt_lifetime_ref(&mut self,
99 opt_lifetime
: &'v Option
<Lifetime
>) {
100 match *opt_lifetime
{
101 Some(ref l
) => self.visit_lifetime_ref(l
),
105 fn visit_lifetime_bound(&mut self, lifetime
: &'v Lifetime
) {
106 walk_lifetime_bound(self, lifetime
)
108 fn visit_lifetime_ref(&mut self, lifetime
: &'v Lifetime
) {
109 walk_lifetime_ref(self, lifetime
)
111 fn visit_lifetime_def(&mut self, lifetime
: &'v LifetimeDef
) {
112 walk_lifetime_def(self, lifetime
)
114 fn visit_explicit_self(&mut self, es
: &'v ExplicitSelf
) {
115 walk_explicit_self(self, es
)
117 fn visit_mac(&mut self, _mac
: &'v Mac
) {
118 panic
!("visit_mac disabled by default");
119 // NB: see note about macros above.
120 // if you really want a visitor that
121 // works on macros, use this
122 // definition in your trait impl:
123 // visit::walk_mac(self, _mac)
125 fn visit_path(&mut self, path
: &'v Path
, _id
: ast
::NodeId
) {
126 walk_path(self, path
)
128 fn visit_path_segment(&mut self, path_span
: Span
, path_segment
: &'v PathSegment
) {
129 walk_path_segment(self, path_span
, path_segment
)
131 fn visit_path_parameters(&mut self, path_span
: Span
, path_parameters
: &'v PathParameters
) {
132 walk_path_parameters(self, path_span
, path_parameters
)
134 fn visit_assoc_type_binding(&mut self, type_binding
: &'v TypeBinding
) {
135 walk_assoc_type_binding(self, type_binding
)
137 fn visit_attribute(&mut self, _attr
: &'v Attribute
) {}
140 pub fn walk_inlined_item
<'v
,V
>(visitor
: &mut V
, item
: &'v InlinedItem
)
141 where V
: Visitor
<'v
> {
143 IIItem(ref i
) => visitor
.visit_item(&**i
),
144 IIForeign(ref i
) => visitor
.visit_foreign_item(&**i
),
145 IITraitItem(_
, ref ti
) => visitor
.visit_trait_item(ti
),
146 IIImplItem(_
, ref ii
) => visitor
.visit_impl_item(ii
),
151 pub fn walk_crate
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, krate
: &'v Crate
) {
152 visitor
.visit_mod(&krate
.module
, krate
.span
, CRATE_NODE_ID
);
153 for attr
in &krate
.attrs
{
154 visitor
.visit_attribute(attr
);
158 pub fn walk_mod
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, module
: &'v Mod
) {
159 for item
in &module
.items
{
160 visitor
.visit_item(&**item
)
164 pub fn walk_local
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, local
: &'v Local
) {
165 visitor
.visit_pat(&*local
.pat
);
166 walk_ty_opt(visitor
, &local
.ty
);
167 walk_expr_opt(visitor
, &local
.init
);
170 pub fn walk_lifetime_def
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
171 lifetime_def
: &'v LifetimeDef
) {
172 visitor
.visit_name(lifetime_def
.lifetime
.span
, lifetime_def
.lifetime
.name
);
173 for bound
in &lifetime_def
.bounds
{
174 visitor
.visit_lifetime_bound(bound
);
178 pub fn walk_lifetime_bound
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
179 lifetime_ref
: &'v Lifetime
) {
180 visitor
.visit_lifetime_ref(lifetime_ref
)
183 pub fn walk_lifetime_ref
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
184 lifetime_ref
: &'v Lifetime
) {
185 visitor
.visit_name(lifetime_ref
.span
, lifetime_ref
.name
)
188 pub fn walk_explicit_self
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
189 explicit_self
: &'v ExplicitSelf
) {
190 match explicit_self
.node
{
191 SelfStatic
| SelfValue(_
) => {}
,
192 SelfRegion(ref lifetime
, _
, _
) => {
193 visitor
.visit_opt_lifetime_ref(explicit_self
.span
, lifetime
)
195 SelfExplicit(ref typ
, _
) => visitor
.visit_ty(&**typ
),
199 pub fn walk_poly_trait_ref
<'v
, V
>(visitor
: &mut V
,
200 trait_ref
: &'v PolyTraitRef
,
201 _modifier
: &'v TraitBoundModifier
)
204 walk_lifetime_decls_helper(visitor
, &trait_ref
.bound_lifetimes
);
205 visitor
.visit_trait_ref(&trait_ref
.trait_ref
);
208 pub fn walk_trait_ref
<'v
,V
>(visitor
: &mut V
,
209 trait_ref
: &'v TraitRef
)
212 visitor
.visit_path(&trait_ref
.path
, trait_ref
.ref_id
)
215 pub fn walk_item
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, item
: &'v Item
) {
216 visitor
.visit_ident(item
.span
, item
.ident
);
218 ItemExternCrate(..) => {}
221 ViewPathSimple(ident
, ref path
) => {
222 visitor
.visit_ident(vp
.span
, ident
);
223 visitor
.visit_path(path
, item
.id
);
225 ViewPathGlob(ref path
) => {
226 visitor
.visit_path(path
, item
.id
);
228 ViewPathList(ref prefix
, ref list
) => {
231 PathListIdent { name, .. }
=> {
232 visitor
.visit_ident(id
.span
, name
);
234 PathListMod { .. }
=> ()
238 // Note that the `prefix` here is not a complete
239 // path, so we don't use `visit_path`.
240 walk_path(visitor
, prefix
);
244 ItemStatic(ref typ
, _
, ref expr
) |
245 ItemConst(ref typ
, ref expr
) => {
246 visitor
.visit_ty(&**typ
);
247 visitor
.visit_expr(&**expr
);
249 ItemFn(ref declaration
, unsafety
, constness
, abi
, ref generics
, ref body
) => {
250 visitor
.visit_fn(FkItemFn(item
.ident
, generics
, unsafety
,
251 constness
, abi
, item
.vis
),
257 ItemMod(ref module
) => {
258 visitor
.visit_mod(module
, item
.span
, item
.id
)
260 ItemForeignMod(ref foreign_module
) => {
261 for foreign_item
in &foreign_module
.items
{
262 visitor
.visit_foreign_item(&**foreign_item
)
265 ItemTy(ref typ
, ref type_parameters
) => {
266 visitor
.visit_ty(&**typ
);
267 visitor
.visit_generics(type_parameters
)
269 ItemEnum(ref enum_definition
, ref type_parameters
) => {
270 visitor
.visit_generics(type_parameters
);
271 walk_enum_def(visitor
, enum_definition
, type_parameters
)
273 ItemDefaultImpl(_
, ref trait_ref
) => {
274 visitor
.visit_trait_ref(trait_ref
)
281 visitor
.visit_generics(type_parameters
);
282 match *trait_reference
{
283 Some(ref trait_reference
) => visitor
.visit_trait_ref(trait_reference
),
286 visitor
.visit_ty(&**typ
);
287 for impl_item
in impl_items
{
288 visitor
.visit_impl_item(impl_item
);
291 ItemStruct(ref struct_definition
, ref generics
) => {
292 visitor
.visit_generics(generics
);
293 visitor
.visit_struct_def(&**struct_definition
,
298 ItemTrait(_
, ref generics
, ref bounds
, ref methods
) => {
299 visitor
.visit_generics(generics
);
300 walk_ty_param_bounds_helper(visitor
, bounds
);
301 for method
in methods
{
302 visitor
.visit_trait_item(method
)
305 ItemMac(ref mac
) => visitor
.visit_mac(mac
),
307 for attr
in &item
.attrs
{
308 visitor
.visit_attribute(attr
);
312 pub fn walk_enum_def
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
313 enum_definition
: &'v EnumDef
,
314 generics
: &'v Generics
) {
315 for variant
in &enum_definition
.variants
{
316 visitor
.visit_variant(&**variant
, generics
);
320 pub fn walk_variant
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
321 variant
: &'v Variant
,
322 generics
: &'v Generics
) {
323 visitor
.visit_ident(variant
.span
, variant
.node
.name
);
325 match variant
.node
.kind
{
326 TupleVariantKind(ref variant_arguments
) => {
327 for variant_argument
in variant_arguments
{
328 visitor
.visit_ty(&*variant_argument
.ty
)
331 StructVariantKind(ref struct_definition
) => {
332 visitor
.visit_struct_def(&**struct_definition
,
338 match variant
.node
.disr_expr
{
339 Some(ref expr
) => visitor
.visit_expr(&**expr
),
342 for attr
in &variant
.node
.attrs
{
343 visitor
.visit_attribute(attr
);
347 pub fn skip_ty
<'v
, V
: Visitor
<'v
>>(_
: &mut V
, _
: &'v Ty
) {
351 pub fn walk_ty_opt
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, optional_type
: &'v Option
<P
<Ty
>>) {
352 match *optional_type
{
353 Some(ref ty
) => visitor
.visit_ty(&**ty
),
358 pub fn walk_ty
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, typ
: &'v Ty
) {
360 TyVec(ref ty
) | TyParen(ref ty
) => {
361 visitor
.visit_ty(&**ty
)
363 TyPtr(ref mutable_type
) => {
364 visitor
.visit_ty(&*mutable_type
.ty
)
366 TyRptr(ref lifetime
, ref mutable_type
) => {
367 visitor
.visit_opt_lifetime_ref(typ
.span
, lifetime
);
368 visitor
.visit_ty(&*mutable_type
.ty
)
370 TyTup(ref tuple_element_types
) => {
371 for tuple_element_type
in tuple_element_types
{
372 visitor
.visit_ty(&**tuple_element_type
)
375 TyBareFn(ref function_declaration
) => {
376 for argument
in &function_declaration
.decl
.inputs
{
377 visitor
.visit_ty(&*argument
.ty
)
379 walk_fn_ret_ty(visitor
, &function_declaration
.decl
.output
);
380 walk_lifetime_decls_helper(visitor
, &function_declaration
.lifetimes
);
382 TyPath(ref maybe_qself
, ref path
) => {
383 if let Some(ref qself
) = *maybe_qself
{
384 visitor
.visit_ty(&qself
.ty
);
386 visitor
.visit_path(path
, typ
.id
);
388 TyObjectSum(ref ty
, ref bounds
) => {
389 visitor
.visit_ty(&**ty
);
390 walk_ty_param_bounds_helper(visitor
, bounds
);
392 TyFixedLengthVec(ref ty
, ref expression
) => {
393 visitor
.visit_ty(&**ty
);
394 visitor
.visit_expr(&**expression
)
396 TyPolyTraitRef(ref bounds
) => {
397 walk_ty_param_bounds_helper(visitor
, bounds
)
399 TyTypeof(ref expression
) => {
400 visitor
.visit_expr(&**expression
)
406 pub fn walk_lifetime_decls_helper
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
407 lifetimes
: &'v Vec
<LifetimeDef
>) {
409 visitor
.visit_lifetime_def(l
);
413 pub fn walk_path
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, path
: &'v Path
) {
414 for segment
in &path
.segments
{
415 visitor
.visit_path_segment(path
.span
, segment
);
419 pub fn walk_path_segment
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
421 segment
: &'v PathSegment
) {
422 visitor
.visit_ident(path_span
, segment
.identifier
);
423 visitor
.visit_path_parameters(path_span
, &segment
.parameters
);
426 pub fn walk_path_parameters
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
428 path_parameters
: &'v PathParameters
) {
429 match *path_parameters
{
430 ast
::AngleBracketedParameters(ref data
) => {
431 for typ
in data
.types
.iter() {
432 visitor
.visit_ty(&**typ
);
434 for lifetime
in &data
.lifetimes
{
435 visitor
.visit_lifetime_ref(lifetime
);
437 for binding
in data
.bindings
.iter() {
438 visitor
.visit_assoc_type_binding(&**binding
);
441 ast
::ParenthesizedParameters(ref data
) => {
442 for typ
in &data
.inputs
{
443 visitor
.visit_ty(&**typ
);
445 if let Some(ref typ
) = data
.output
{
446 visitor
.visit_ty(&**typ
);
452 pub fn walk_assoc_type_binding
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
453 type_binding
: &'v TypeBinding
) {
454 visitor
.visit_ident(type_binding
.span
, type_binding
.ident
);
455 visitor
.visit_ty(&*type_binding
.ty
);
458 pub fn walk_pat
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, pattern
: &'v Pat
) {
460 PatEnum(ref path
, ref children
) => {
461 visitor
.visit_path(path
, pattern
.id
);
462 if let Some(ref children
) = *children
{
463 for child
in children
{
464 visitor
.visit_pat(&*child
)
468 PatQPath(ref qself
, ref path
) => {
469 visitor
.visit_ty(&qself
.ty
);
470 visitor
.visit_path(path
, pattern
.id
)
472 PatStruct(ref path
, ref fields
, _
) => {
473 visitor
.visit_path(path
, pattern
.id
);
474 for field
in fields
{
475 visitor
.visit_pat(&*field
.node
.pat
)
478 PatTup(ref tuple_elements
) => {
479 for tuple_element
in tuple_elements
{
480 visitor
.visit_pat(&**tuple_element
)
483 PatBox(ref subpattern
) |
484 PatRegion(ref subpattern
, _
) => {
485 visitor
.visit_pat(&**subpattern
)
487 PatIdent(_
, ref pth1
, ref optional_subpattern
) => {
488 visitor
.visit_ident(pth1
.span
, pth1
.node
);
489 match *optional_subpattern
{
491 Some(ref subpattern
) => visitor
.visit_pat(&**subpattern
),
494 PatLit(ref expression
) => visitor
.visit_expr(&**expression
),
495 PatRange(ref lower_bound
, ref upper_bound
) => {
496 visitor
.visit_expr(&**lower_bound
);
497 visitor
.visit_expr(&**upper_bound
)
500 PatVec(ref prepattern
, ref slice_pattern
, ref postpatterns
) => {
501 for prepattern
in prepattern
{
502 visitor
.visit_pat(&**prepattern
)
504 if let Some(ref slice_pattern
) = *slice_pattern
{
505 visitor
.visit_pat(&**slice_pattern
)
507 for postpattern
in postpatterns
{
508 visitor
.visit_pat(&**postpattern
)
511 PatMac(ref mac
) => visitor
.visit_mac(mac
),
515 pub fn walk_foreign_item
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
516 foreign_item
: &'v ForeignItem
) {
517 visitor
.visit_ident(foreign_item
.span
, foreign_item
.ident
);
519 match foreign_item
.node
{
520 ForeignItemFn(ref function_declaration
, ref generics
) => {
521 walk_fn_decl(visitor
, &**function_declaration
);
522 visitor
.visit_generics(generics
)
524 ForeignItemStatic(ref typ
, _
) => visitor
.visit_ty(&**typ
),
527 for attr
in &foreign_item
.attrs
{
528 visitor
.visit_attribute(attr
);
532 pub fn walk_ty_param_bounds_helper
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
533 bounds
: &'v OwnedSlice
<TyParamBound
>) {
534 for bound
in bounds
.iter() {
535 visitor
.visit_ty_param_bound(bound
)
539 pub fn walk_ty_param_bound
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
540 bound
: &'v TyParamBound
) {
542 TraitTyParamBound(ref typ
, ref modifier
) => {
543 visitor
.visit_poly_trait_ref(typ
, modifier
);
545 RegionTyParamBound(ref lifetime
) => {
546 visitor
.visit_lifetime_bound(lifetime
);
551 pub fn walk_generics
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, generics
: &'v Generics
) {
552 for param
in generics
.ty_params
.iter() {
553 visitor
.visit_ident(param
.span
, param
.ident
);
554 walk_ty_param_bounds_helper(visitor
, ¶m
.bounds
);
555 walk_ty_opt(visitor
, ¶m
.default);
557 walk_lifetime_decls_helper(visitor
, &generics
.lifetimes
);
558 for predicate
in &generics
.where_clause
.predicates
{
560 &ast
::WherePredicate
::BoundPredicate(ast
::WhereBoundPredicate
{ref bounded_ty
,
563 visitor
.visit_ty(&**bounded_ty
);
564 walk_ty_param_bounds_helper(visitor
, bounds
);
566 &ast
::WherePredicate
::RegionPredicate(ast
::WhereRegionPredicate
{ref lifetime
,
569 visitor
.visit_lifetime_ref(lifetime
);
571 for bound
in bounds
{
572 visitor
.visit_lifetime_ref(bound
);
575 &ast
::WherePredicate
::EqPredicate(ast
::WhereEqPredicate
{id
,
579 visitor
.visit_path(path
, id
);
580 visitor
.visit_ty(&**ty
);
586 pub fn walk_fn_ret_ty
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, ret_ty
: &'v FunctionRetTy
) {
587 if let Return(ref output_ty
) = *ret_ty
{
588 visitor
.visit_ty(&**output_ty
)
592 pub fn walk_fn_decl
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, function_declaration
: &'v FnDecl
) {
593 for argument
in &function_declaration
.inputs
{
594 visitor
.visit_pat(&*argument
.pat
);
595 visitor
.visit_ty(&*argument
.ty
)
597 walk_fn_ret_ty(visitor
, &function_declaration
.output
)
600 pub fn walk_fn
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
601 function_kind
: FnKind
<'v
>,
602 function_declaration
: &'v FnDecl
,
603 function_body
: &'v Block
,
605 walk_fn_decl(visitor
, function_declaration
);
607 match function_kind
{
608 FkItemFn(_
, generics
, _
, _
, _
, _
) => {
609 visitor
.visit_generics(generics
);
611 FkMethod(_
, sig
, _
) => {
612 visitor
.visit_generics(&sig
.generics
);
613 visitor
.visit_explicit_self(&sig
.explicit_self
);
618 visitor
.visit_block(function_body
)
621 pub fn walk_trait_item
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, trait_item
: &'v TraitItem
) {
622 visitor
.visit_ident(trait_item
.span
, trait_item
.ident
);
623 for attr
in &trait_item
.attrs
{
624 visitor
.visit_attribute(attr
);
626 match trait_item
.node
{
627 ConstTraitItem(ref ty
, ref default) => {
628 visitor
.visit_ty(ty
);
629 if let Some(ref expr
) = *default {
630 visitor
.visit_expr(expr
);
633 MethodTraitItem(ref sig
, None
) => {
634 visitor
.visit_explicit_self(&sig
.explicit_self
);
635 visitor
.visit_generics(&sig
.generics
);
636 walk_fn_decl(visitor
, &sig
.decl
);
638 MethodTraitItem(ref sig
, Some(ref body
)) => {
639 visitor
.visit_fn(FkMethod(trait_item
.ident
, sig
, None
), &sig
.decl
,
640 body
, trait_item
.span
, trait_item
.id
);
642 TypeTraitItem(ref bounds
, ref default) => {
643 walk_ty_param_bounds_helper(visitor
, bounds
);
644 walk_ty_opt(visitor
, default);
649 pub fn walk_impl_item
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, impl_item
: &'v ImplItem
) {
650 visitor
.visit_ident(impl_item
.span
, impl_item
.ident
);
651 for attr
in &impl_item
.attrs
{
652 visitor
.visit_attribute(attr
);
654 match impl_item
.node
{
655 ConstImplItem(ref ty
, ref expr
) => {
656 visitor
.visit_ty(ty
);
657 visitor
.visit_expr(expr
);
659 MethodImplItem(ref sig
, ref body
) => {
660 visitor
.visit_fn(FkMethod(impl_item
.ident
, sig
, Some(impl_item
.vis
)), &sig
.decl
,
661 body
, impl_item
.span
, impl_item
.id
);
663 TypeImplItem(ref ty
) => {
664 visitor
.visit_ty(ty
);
666 MacImplItem(ref mac
) => {
667 visitor
.visit_mac(mac
);
672 pub fn walk_struct_def
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
673 struct_definition
: &'v StructDef
) {
674 for field
in &struct_definition
.fields
{
675 visitor
.visit_struct_field(field
)
679 pub fn walk_struct_field
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
680 struct_field
: &'v StructField
) {
681 if let NamedField(name
, _
) = struct_field
.node
.kind
{
682 visitor
.visit_ident(struct_field
.span
, name
);
685 visitor
.visit_ty(&*struct_field
.node
.ty
);
687 for attr
in &struct_field
.node
.attrs
{
688 visitor
.visit_attribute(attr
);
692 pub fn walk_block
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, block
: &'v Block
) {
693 for statement
in &block
.stmts
{
694 visitor
.visit_stmt(&**statement
)
696 walk_expr_opt(visitor
, &block
.expr
)
699 pub fn walk_stmt
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, statement
: &'v Stmt
) {
700 match statement
.node
{
701 StmtDecl(ref declaration
, _
) => visitor
.visit_decl(&**declaration
),
702 StmtExpr(ref expression
, _
) | StmtSemi(ref expression
, _
) => {
703 visitor
.visit_expr(&**expression
)
705 StmtMac(ref mac
, _
) => visitor
.visit_mac(&**mac
),
709 pub fn walk_decl
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, declaration
: &'v Decl
) {
710 match declaration
.node
{
711 DeclLocal(ref local
) => visitor
.visit_local(&**local
),
712 DeclItem(ref item
) => visitor
.visit_item(&**item
),
716 pub fn walk_expr_opt
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
717 optional_expression
: &'v Option
<P
<Expr
>>) {
718 match *optional_expression
{
720 Some(ref expression
) => visitor
.visit_expr(&**expression
),
724 pub fn walk_exprs
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, expressions
: &'v
[P
<Expr
>]) {
725 for expression
in expressions
{
726 visitor
.visit_expr(&**expression
)
730 pub fn walk_mac
<'v
, V
: Visitor
<'v
>>(_
: &mut V
, _
: &'v Mac
) {
734 pub fn walk_expr
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, expression
: &'v Expr
) {
735 match expression
.node
{
736 ExprBox(ref place
, ref subexpression
) => {
737 place
.as_ref().map(|e
|visitor
.visit_expr(&**e
));
738 visitor
.visit_expr(&**subexpression
)
740 ExprVec(ref subexpressions
) => {
741 walk_exprs(visitor
, subexpressions
)
743 ExprRepeat(ref element
, ref count
) => {
744 visitor
.visit_expr(&**element
);
745 visitor
.visit_expr(&**count
)
747 ExprStruct(ref path
, ref fields
, ref optional_base
) => {
748 visitor
.visit_path(path
, expression
.id
);
749 for field
in fields
{
750 visitor
.visit_expr(&*field
.expr
)
752 walk_expr_opt(visitor
, optional_base
)
754 ExprTup(ref subexpressions
) => {
755 for subexpression
in subexpressions
{
756 visitor
.visit_expr(&**subexpression
)
759 ExprCall(ref callee_expression
, ref arguments
) => {
760 for argument
in arguments
{
761 visitor
.visit_expr(&**argument
)
763 visitor
.visit_expr(&**callee_expression
)
765 ExprMethodCall(_
, ref types
, ref arguments
) => {
766 walk_exprs(visitor
, arguments
);
768 visitor
.visit_ty(&**typ
)
771 ExprBinary(_
, ref left_expression
, ref right_expression
) => {
772 visitor
.visit_expr(&**left_expression
);
773 visitor
.visit_expr(&**right_expression
)
775 ExprAddrOf(_
, ref subexpression
) | ExprUnary(_
, ref subexpression
) => {
776 visitor
.visit_expr(&**subexpression
)
779 ExprCast(ref subexpression
, ref typ
) => {
780 visitor
.visit_expr(&**subexpression
);
781 visitor
.visit_ty(&**typ
)
783 ExprIf(ref head_expression
, ref if_block
, ref optional_else
) => {
784 visitor
.visit_expr(&**head_expression
);
785 visitor
.visit_block(&**if_block
);
786 walk_expr_opt(visitor
, optional_else
)
788 ExprWhile(ref subexpression
, ref block
, _
) => {
789 visitor
.visit_expr(&**subexpression
);
790 visitor
.visit_block(&**block
)
792 ExprIfLet(ref pattern
, ref subexpression
, ref if_block
, ref optional_else
) => {
793 visitor
.visit_pat(&**pattern
);
794 visitor
.visit_expr(&**subexpression
);
795 visitor
.visit_block(&**if_block
);
796 walk_expr_opt(visitor
, optional_else
);
798 ExprWhileLet(ref pattern
, ref subexpression
, ref block
, _
) => {
799 visitor
.visit_pat(&**pattern
);
800 visitor
.visit_expr(&**subexpression
);
801 visitor
.visit_block(&**block
);
803 ExprForLoop(ref pattern
, ref subexpression
, ref block
, _
) => {
804 visitor
.visit_pat(&**pattern
);
805 visitor
.visit_expr(&**subexpression
);
806 visitor
.visit_block(&**block
)
808 ExprLoop(ref block
, _
) => visitor
.visit_block(&**block
),
809 ExprMatch(ref subexpression
, ref arms
, _
) => {
810 visitor
.visit_expr(&**subexpression
);
812 visitor
.visit_arm(arm
)
815 ExprClosure(_
, ref function_declaration
, ref body
) => {
816 visitor
.visit_fn(FkFnBlock
,
817 &**function_declaration
,
822 ExprBlock(ref block
) => visitor
.visit_block(&**block
),
823 ExprAssign(ref left_hand_expression
, ref right_hand_expression
) => {
824 visitor
.visit_expr(&**right_hand_expression
);
825 visitor
.visit_expr(&**left_hand_expression
)
827 ExprAssignOp(_
, ref left_expression
, ref right_expression
) => {
828 visitor
.visit_expr(&**right_expression
);
829 visitor
.visit_expr(&**left_expression
)
831 ExprField(ref subexpression
, _
) => {
832 visitor
.visit_expr(&**subexpression
);
834 ExprTupField(ref subexpression
, _
) => {
835 visitor
.visit_expr(&**subexpression
);
837 ExprIndex(ref main_expression
, ref index_expression
) => {
838 visitor
.visit_expr(&**main_expression
);
839 visitor
.visit_expr(&**index_expression
)
841 ExprRange(ref start
, ref end
) => {
842 walk_expr_opt(visitor
, start
);
843 walk_expr_opt(visitor
, end
)
845 ExprPath(ref maybe_qself
, ref path
) => {
846 if let Some(ref qself
) = *maybe_qself
{
847 visitor
.visit_ty(&qself
.ty
);
849 visitor
.visit_path(path
, expression
.id
)
851 ExprBreak(_
) | ExprAgain(_
) => {}
852 ExprRet(ref optional_expression
) => {
853 walk_expr_opt(visitor
, optional_expression
)
855 ExprMac(ref mac
) => visitor
.visit_mac(mac
),
856 ExprParen(ref subexpression
) => {
857 visitor
.visit_expr(&**subexpression
)
859 ExprInlineAsm(ref ia
) => {
860 for input
in &ia
.inputs
{
861 let (_
, ref input
) = *input
;
862 visitor
.visit_expr(&**input
)
864 for output
in &ia
.outputs
{
865 let (_
, ref output
, _
) = *output
;
866 visitor
.visit_expr(&**output
)
871 visitor
.visit_expr_post(expression
)
874 pub fn walk_arm
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, arm
: &'v Arm
) {
875 for pattern
in &arm
.pats
{
876 visitor
.visit_pat(&**pattern
)
878 walk_expr_opt(visitor
, &arm
.guard
);
879 visitor
.visit_expr(&*arm
.body
);
880 for attr
in &arm
.attrs
{
881 visitor
.visit_attribute(attr
);