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.
31 use owned_slice
::OwnedSlice
;
33 #[derive(Copy, Clone, PartialEq, Eq)]
35 /// fn foo() or extern "Abi" fn foo()
36 ItemFn(Ident
, &'a Generics
, Unsafety
, Constness
, Abi
, Visibility
),
39 Method(Ident
, &'a MethodSig
, Option
<Visibility
>),
45 /// Each method of the Visitor trait is a hook to be potentially
46 /// overridden. Each method's default implementation recursively visits
47 /// the substructure of the input via the corresponding `walk` method;
48 /// e.g. the `visit_mod` method by default calls `visit::walk_mod`.
50 /// If you want to ensure that your code handles every variant
51 /// explicitly, you need to override each method. (And you also need
52 /// to monitor future changes to `Visitor` in case a new method with a
53 /// new default implementation gets introduced.)
54 pub trait Visitor
<'v
> : Sized
{
55 fn visit_name(&mut self, _span
: Span
, _name
: Name
) {
58 fn visit_ident(&mut self, span
: Span
, ident
: Ident
) {
59 self.visit_name(span
, ident
.name
);
61 fn visit_mod(&mut self, m
: &'v Mod
, _s
: Span
, _n
: NodeId
) { walk_mod(self, m) }
62 fn visit_foreign_item(&mut self, i
: &'v ForeignItem
) { walk_foreign_item(self, i) }
63 fn visit_item(&mut self, i
: &'v Item
) { walk_item(self, i) }
64 fn visit_local(&mut self, l
: &'v Local
) { walk_local(self, l) }
65 fn visit_block(&mut self, b
: &'v Block
) { walk_block(self, b) }
66 fn visit_stmt(&mut self, s
: &'v Stmt
) { walk_stmt(self, s) }
67 fn visit_arm(&mut self, a
: &'v Arm
) { walk_arm(self, a) }
68 fn visit_pat(&mut self, p
: &'v Pat
) { walk_pat(self, p) }
69 fn visit_decl(&mut self, d
: &'v Decl
) { walk_decl(self, d) }
70 fn visit_expr(&mut self, ex
: &'v Expr
) { walk_expr(self, ex) }
71 fn visit_expr_post(&mut self, _ex
: &'v Expr
) { }
72 fn visit_ty(&mut self, t
: &'v Ty
) { walk_ty(self, t) }
73 fn visit_generics(&mut self, g
: &'v Generics
) { walk_generics(self, g) }
74 fn visit_fn(&mut self, fk
: FnKind
<'v
>, fd
: &'v FnDecl
, b
: &'v Block
, s
: Span
, _
: NodeId
) {
75 walk_fn(self, fk
, fd
, b
, s
)
77 fn visit_trait_item(&mut self, ti
: &'v TraitItem
) { walk_trait_item(self, ti) }
78 fn visit_impl_item(&mut self, ii
: &'v ImplItem
) { walk_impl_item(self, ii) }
79 fn visit_trait_ref(&mut self, t
: &'v TraitRef
) { walk_trait_ref(self, t) }
80 fn visit_ty_param_bound(&mut self, bounds
: &'v TyParamBound
) {
81 walk_ty_param_bound(self, bounds
)
83 fn visit_poly_trait_ref(&mut self, t
: &'v PolyTraitRef
, m
: &'v TraitBoundModifier
) {
84 walk_poly_trait_ref(self, t
, m
)
86 fn visit_struct_def(&mut self, s
: &'v StructDef
, _
: Ident
, _
: &'v Generics
, _
: NodeId
) {
87 walk_struct_def(self, s
)
89 fn visit_struct_field(&mut self, s
: &'v StructField
) { walk_struct_field(self, s) }
90 fn visit_enum_def(&mut self, enum_definition
: &'v EnumDef
,
91 generics
: &'v Generics
) {
92 walk_enum_def(self, enum_definition
, generics
)
95 fn visit_variant(&mut self, v
: &'v Variant
, g
: &'v Generics
) { walk_variant(self, v, g) }
97 /// Visits an optional reference to a lifetime. The `span` is the span of some surrounding
98 /// reference should opt_lifetime be None.
99 fn visit_opt_lifetime_ref(&mut self,
101 opt_lifetime
: &'v Option
<Lifetime
>) {
102 match *opt_lifetime
{
103 Some(ref l
) => self.visit_lifetime_ref(l
),
107 fn visit_lifetime_bound(&mut self, lifetime
: &'v Lifetime
) {
108 walk_lifetime_bound(self, lifetime
)
110 fn visit_lifetime_ref(&mut self, lifetime
: &'v Lifetime
) {
111 walk_lifetime_ref(self, lifetime
)
113 fn visit_lifetime_def(&mut self, lifetime
: &'v LifetimeDef
) {
114 walk_lifetime_def(self, lifetime
)
116 fn visit_explicit_self(&mut self, es
: &'v ExplicitSelf
) {
117 walk_explicit_self(self, es
)
119 fn visit_mac(&mut self, _mac
: &'v Mac
) {
120 panic
!("visit_mac disabled by default");
121 // NB: see note about macros above.
122 // if you really want a visitor that
123 // works on macros, use this
124 // definition in your trait impl:
125 // visit::walk_mac(self, _mac)
127 fn visit_path(&mut self, path
: &'v Path
, _id
: ast
::NodeId
) {
128 walk_path(self, path
)
130 fn visit_path_segment(&mut self, path_span
: Span
, path_segment
: &'v PathSegment
) {
131 walk_path_segment(self, path_span
, path_segment
)
133 fn visit_path_parameters(&mut self, path_span
: Span
, path_parameters
: &'v PathParameters
) {
134 walk_path_parameters(self, path_span
, path_parameters
)
136 fn visit_assoc_type_binding(&mut self, type_binding
: &'v TypeBinding
) {
137 walk_assoc_type_binding(self, type_binding
)
139 fn visit_attribute(&mut self, _attr
: &'v Attribute
) {}
142 pub fn walk_crate
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, krate
: &'v Crate
) {
143 visitor
.visit_mod(&krate
.module
, krate
.span
, CRATE_NODE_ID
);
144 for attr
in &krate
.attrs
{
145 visitor
.visit_attribute(attr
);
149 pub fn walk_mod
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, module
: &'v Mod
) {
150 for item
in &module
.items
{
151 visitor
.visit_item(&**item
)
155 pub fn walk_local
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, local
: &'v Local
) {
156 visitor
.visit_pat(&*local
.pat
);
157 walk_ty_opt(visitor
, &local
.ty
);
158 walk_expr_opt(visitor
, &local
.init
);
161 pub fn walk_lifetime_def
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
162 lifetime_def
: &'v LifetimeDef
) {
163 visitor
.visit_name(lifetime_def
.lifetime
.span
, lifetime_def
.lifetime
.name
);
164 for bound
in &lifetime_def
.bounds
{
165 visitor
.visit_lifetime_bound(bound
);
169 pub fn walk_lifetime_bound
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
170 lifetime_ref
: &'v Lifetime
) {
171 visitor
.visit_lifetime_ref(lifetime_ref
)
174 pub fn walk_lifetime_ref
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
175 lifetime_ref
: &'v Lifetime
) {
176 visitor
.visit_name(lifetime_ref
.span
, lifetime_ref
.name
)
179 pub fn walk_explicit_self
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
180 explicit_self
: &'v ExplicitSelf
) {
181 match explicit_self
.node
{
182 SelfStatic
| SelfValue(_
) => {}
,
183 SelfRegion(ref lifetime
, _
, _
) => {
184 visitor
.visit_opt_lifetime_ref(explicit_self
.span
, lifetime
)
186 SelfExplicit(ref typ
, _
) => visitor
.visit_ty(&**typ
),
190 pub fn walk_poly_trait_ref
<'v
, V
>(visitor
: &mut V
,
191 trait_ref
: &'v PolyTraitRef
,
192 _modifier
: &'v TraitBoundModifier
)
195 walk_lifetime_decls_helper(visitor
, &trait_ref
.bound_lifetimes
);
196 visitor
.visit_trait_ref(&trait_ref
.trait_ref
);
199 pub fn walk_trait_ref
<'v
,V
>(visitor
: &mut V
,
200 trait_ref
: &'v TraitRef
)
203 visitor
.visit_path(&trait_ref
.path
, trait_ref
.ref_id
)
206 pub fn walk_item
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, item
: &'v Item
) {
207 visitor
.visit_ident(item
.span
, item
.ident
);
209 ItemExternCrate(..) => {}
212 ViewPathSimple(ident
, ref path
) => {
213 visitor
.visit_ident(vp
.span
, ident
);
214 visitor
.visit_path(path
, item
.id
);
216 ViewPathGlob(ref path
) => {
217 visitor
.visit_path(path
, item
.id
);
219 ViewPathList(ref prefix
, ref list
) => {
222 PathListIdent { name, rename, .. }
=> {
223 visitor
.visit_ident(id
.span
, name
);
224 if let Some(ident
) = rename
{
225 visitor
.visit_ident(id
.span
, ident
);
228 PathListMod { rename, .. }
=> {
229 if let Some(ident
) = rename
{
230 visitor
.visit_ident(id
.span
, ident
);
236 // Note that the `prefix` here is not a complete
237 // path, so we don't use `visit_path`.
238 walk_path(visitor
, prefix
);
242 ItemStatic(ref typ
, _
, ref expr
) |
243 ItemConst(ref typ
, ref expr
) => {
244 visitor
.visit_ty(&**typ
);
245 visitor
.visit_expr(&**expr
);
247 ItemFn(ref declaration
, unsafety
, constness
, abi
, ref generics
, ref body
) => {
248 visitor
.visit_fn(FnKind
::ItemFn(item
.ident
, generics
, unsafety
,
249 constness
, abi
, item
.vis
),
255 ItemMod(ref module
) => {
256 visitor
.visit_mod(module
, item
.span
, item
.id
)
258 ItemForeignMod(ref foreign_module
) => {
259 for foreign_item
in &foreign_module
.items
{
260 visitor
.visit_foreign_item(&**foreign_item
)
263 ItemTy(ref typ
, ref type_parameters
) => {
264 visitor
.visit_ty(&**typ
);
265 visitor
.visit_generics(type_parameters
)
267 ItemEnum(ref enum_definition
, ref type_parameters
) => {
268 visitor
.visit_generics(type_parameters
);
269 visitor
.visit_enum_def(enum_definition
, type_parameters
)
271 ItemDefaultImpl(_
, ref trait_ref
) => {
272 visitor
.visit_trait_ref(trait_ref
)
279 visitor
.visit_generics(type_parameters
);
280 match *trait_reference
{
281 Some(ref trait_reference
) => visitor
.visit_trait_ref(trait_reference
),
284 visitor
.visit_ty(&**typ
);
285 for impl_item
in impl_items
{
286 visitor
.visit_impl_item(impl_item
);
289 ItemStruct(ref struct_definition
, ref generics
) => {
290 visitor
.visit_generics(generics
);
291 visitor
.visit_struct_def(&**struct_definition
,
296 ItemTrait(_
, ref generics
, ref bounds
, ref methods
) => {
297 visitor
.visit_generics(generics
);
298 walk_ty_param_bounds_helper(visitor
, bounds
);
299 for method
in methods
{
300 visitor
.visit_trait_item(method
)
303 ItemMac(ref mac
) => visitor
.visit_mac(mac
),
305 for attr
in &item
.attrs
{
306 visitor
.visit_attribute(attr
);
310 pub fn walk_enum_def
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
311 enum_definition
: &'v EnumDef
,
312 generics
: &'v Generics
) {
313 for variant
in &enum_definition
.variants
{
314 visitor
.visit_variant(&**variant
, generics
);
318 pub fn walk_variant
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
319 variant
: &'v Variant
,
320 generics
: &'v Generics
) {
321 visitor
.visit_ident(variant
.span
, variant
.node
.name
);
323 match variant
.node
.kind
{
324 TupleVariantKind(ref variant_arguments
) => {
325 for variant_argument
in variant_arguments
{
326 visitor
.visit_ty(&*variant_argument
.ty
)
329 StructVariantKind(ref struct_definition
) => {
330 visitor
.visit_struct_def(&**struct_definition
,
336 match variant
.node
.disr_expr
{
337 Some(ref expr
) => visitor
.visit_expr(&**expr
),
340 for attr
in &variant
.node
.attrs
{
341 visitor
.visit_attribute(attr
);
345 pub fn skip_ty
<'v
, V
: Visitor
<'v
>>(_
: &mut V
, _
: &'v Ty
) {
349 pub fn walk_ty_opt
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, optional_type
: &'v Option
<P
<Ty
>>) {
350 match *optional_type
{
351 Some(ref ty
) => visitor
.visit_ty(&**ty
),
356 pub fn walk_ty
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, typ
: &'v Ty
) {
358 TyVec(ref ty
) | TyParen(ref ty
) => {
359 visitor
.visit_ty(&**ty
)
361 TyPtr(ref mutable_type
) => {
362 visitor
.visit_ty(&*mutable_type
.ty
)
364 TyRptr(ref lifetime
, ref mutable_type
) => {
365 visitor
.visit_opt_lifetime_ref(typ
.span
, lifetime
);
366 visitor
.visit_ty(&*mutable_type
.ty
)
368 TyTup(ref tuple_element_types
) => {
369 for tuple_element_type
in tuple_element_types
{
370 visitor
.visit_ty(&**tuple_element_type
)
373 TyBareFn(ref function_declaration
) => {
374 for argument
in &function_declaration
.decl
.inputs
{
375 visitor
.visit_ty(&*argument
.ty
)
377 walk_fn_ret_ty(visitor
, &function_declaration
.decl
.output
);
378 walk_lifetime_decls_helper(visitor
, &function_declaration
.lifetimes
);
380 TyPath(ref maybe_qself
, ref path
) => {
381 if let Some(ref qself
) = *maybe_qself
{
382 visitor
.visit_ty(&qself
.ty
);
384 visitor
.visit_path(path
, typ
.id
);
386 TyObjectSum(ref ty
, ref bounds
) => {
387 visitor
.visit_ty(&**ty
);
388 walk_ty_param_bounds_helper(visitor
, bounds
);
390 TyFixedLengthVec(ref ty
, ref expression
) => {
391 visitor
.visit_ty(&**ty
);
392 visitor
.visit_expr(&**expression
)
394 TyPolyTraitRef(ref bounds
) => {
395 walk_ty_param_bounds_helper(visitor
, bounds
)
397 TyTypeof(ref expression
) => {
398 visitor
.visit_expr(&**expression
)
402 visitor
.visit_mac(mac
)
407 pub fn walk_lifetime_decls_helper
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
408 lifetimes
: &'v Vec
<LifetimeDef
>) {
410 visitor
.visit_lifetime_def(l
);
414 pub fn walk_path
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, path
: &'v Path
) {
415 for segment
in &path
.segments
{
416 visitor
.visit_path_segment(path
.span
, segment
);
420 pub fn walk_path_segment
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
422 segment
: &'v PathSegment
) {
423 visitor
.visit_ident(path_span
, segment
.identifier
);
424 visitor
.visit_path_parameters(path_span
, &segment
.parameters
);
427 pub fn walk_path_parameters
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
429 path_parameters
: &'v PathParameters
) {
430 match *path_parameters
{
431 ast
::AngleBracketedParameters(ref data
) => {
432 for typ
in data
.types
.iter() {
433 visitor
.visit_ty(&**typ
);
435 for lifetime
in &data
.lifetimes
{
436 visitor
.visit_lifetime_ref(lifetime
);
438 for binding
in data
.bindings
.iter() {
439 visitor
.visit_assoc_type_binding(&**binding
);
442 ast
::ParenthesizedParameters(ref data
) => {
443 for typ
in &data
.inputs
{
444 visitor
.visit_ty(&**typ
);
446 if let Some(ref typ
) = data
.output
{
447 visitor
.visit_ty(&**typ
);
453 pub fn walk_assoc_type_binding
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
454 type_binding
: &'v TypeBinding
) {
455 visitor
.visit_ident(type_binding
.span
, type_binding
.ident
);
456 visitor
.visit_ty(&*type_binding
.ty
);
459 pub fn walk_pat
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, pattern
: &'v Pat
) {
461 PatEnum(ref path
, ref children
) => {
462 visitor
.visit_path(path
, pattern
.id
);
463 if let Some(ref children
) = *children
{
464 for child
in children
{
465 visitor
.visit_pat(&*child
)
469 PatQPath(ref qself
, ref path
) => {
470 visitor
.visit_ty(&qself
.ty
);
471 visitor
.visit_path(path
, pattern
.id
)
473 PatStruct(ref path
, ref fields
, _
) => {
474 visitor
.visit_path(path
, pattern
.id
);
475 for field
in fields
{
476 visitor
.visit_pat(&*field
.node
.pat
)
479 PatTup(ref tuple_elements
) => {
480 for tuple_element
in tuple_elements
{
481 visitor
.visit_pat(&**tuple_element
)
484 PatBox(ref subpattern
) |
485 PatRegion(ref subpattern
, _
) => {
486 visitor
.visit_pat(&**subpattern
)
488 PatIdent(_
, ref pth1
, ref optional_subpattern
) => {
489 visitor
.visit_ident(pth1
.span
, pth1
.node
);
490 match *optional_subpattern
{
492 Some(ref subpattern
) => visitor
.visit_pat(&**subpattern
),
495 PatLit(ref expression
) => visitor
.visit_expr(&**expression
),
496 PatRange(ref lower_bound
, ref upper_bound
) => {
497 visitor
.visit_expr(&**lower_bound
);
498 visitor
.visit_expr(&**upper_bound
)
501 PatVec(ref prepattern
, ref slice_pattern
, ref postpatterns
) => {
502 for prepattern
in prepattern
{
503 visitor
.visit_pat(&**prepattern
)
505 if let Some(ref slice_pattern
) = *slice_pattern
{
506 visitor
.visit_pat(&**slice_pattern
)
508 for postpattern
in postpatterns
{
509 visitor
.visit_pat(&**postpattern
)
512 PatMac(ref mac
) => visitor
.visit_mac(mac
),
516 pub fn walk_foreign_item
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
517 foreign_item
: &'v ForeignItem
) {
518 visitor
.visit_ident(foreign_item
.span
, foreign_item
.ident
);
520 match foreign_item
.node
{
521 ForeignItemFn(ref function_declaration
, ref generics
) => {
522 walk_fn_decl(visitor
, &**function_declaration
);
523 visitor
.visit_generics(generics
)
525 ForeignItemStatic(ref typ
, _
) => visitor
.visit_ty(&**typ
),
528 for attr
in &foreign_item
.attrs
{
529 visitor
.visit_attribute(attr
);
533 pub fn walk_ty_param_bounds_helper
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
534 bounds
: &'v OwnedSlice
<TyParamBound
>) {
535 for bound
in bounds
.iter() {
536 visitor
.visit_ty_param_bound(bound
)
540 pub fn walk_ty_param_bound
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
541 bound
: &'v TyParamBound
) {
543 TraitTyParamBound(ref typ
, ref modifier
) => {
544 visitor
.visit_poly_trait_ref(typ
, modifier
);
546 RegionTyParamBound(ref lifetime
) => {
547 visitor
.visit_lifetime_bound(lifetime
);
552 pub fn walk_generics
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, generics
: &'v Generics
) {
553 for param
in generics
.ty_params
.iter() {
554 visitor
.visit_ident(param
.span
, param
.ident
);
555 walk_ty_param_bounds_helper(visitor
, ¶m
.bounds
);
556 walk_ty_opt(visitor
, ¶m
.default);
558 walk_lifetime_decls_helper(visitor
, &generics
.lifetimes
);
559 for predicate
in &generics
.where_clause
.predicates
{
561 &ast
::WherePredicate
::BoundPredicate(ast
::WhereBoundPredicate
{ref bounded_ty
,
564 visitor
.visit_ty(&**bounded_ty
);
565 walk_ty_param_bounds_helper(visitor
, bounds
);
567 &ast
::WherePredicate
::RegionPredicate(ast
::WhereRegionPredicate
{ref lifetime
,
570 visitor
.visit_lifetime_ref(lifetime
);
572 for bound
in bounds
{
573 visitor
.visit_lifetime_ref(bound
);
576 &ast
::WherePredicate
::EqPredicate(ast
::WhereEqPredicate
{id
,
580 visitor
.visit_path(path
, id
);
581 visitor
.visit_ty(&**ty
);
587 pub fn walk_fn_ret_ty
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, ret_ty
: &'v FunctionRetTy
) {
588 if let Return(ref output_ty
) = *ret_ty
{
589 visitor
.visit_ty(&**output_ty
)
593 pub fn walk_fn_decl
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, function_declaration
: &'v FnDecl
) {
594 for argument
in &function_declaration
.inputs
{
595 visitor
.visit_pat(&*argument
.pat
);
596 visitor
.visit_ty(&*argument
.ty
)
598 walk_fn_ret_ty(visitor
, &function_declaration
.output
)
601 pub fn walk_fn
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
602 function_kind
: FnKind
<'v
>,
603 function_declaration
: &'v FnDecl
,
604 function_body
: &'v Block
,
606 walk_fn_decl(visitor
, function_declaration
);
608 match function_kind
{
609 FnKind
::ItemFn(_
, generics
, _
, _
, _
, _
) => {
610 visitor
.visit_generics(generics
);
612 FnKind
::Method(_
, sig
, _
) => {
613 visitor
.visit_generics(&sig
.generics
);
614 visitor
.visit_explicit_self(&sig
.explicit_self
);
616 FnKind
::Closure(..) => {}
619 visitor
.visit_block(function_body
)
622 pub fn walk_trait_item
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, trait_item
: &'v TraitItem
) {
623 visitor
.visit_ident(trait_item
.span
, trait_item
.ident
);
624 for attr
in &trait_item
.attrs
{
625 visitor
.visit_attribute(attr
);
627 match trait_item
.node
{
628 ConstTraitItem(ref ty
, ref default) => {
629 visitor
.visit_ty(ty
);
630 if let Some(ref expr
) = *default {
631 visitor
.visit_expr(expr
);
634 MethodTraitItem(ref sig
, None
) => {
635 visitor
.visit_explicit_self(&sig
.explicit_self
);
636 visitor
.visit_generics(&sig
.generics
);
637 walk_fn_decl(visitor
, &sig
.decl
);
639 MethodTraitItem(ref sig
, Some(ref body
)) => {
640 visitor
.visit_fn(FnKind
::Method(trait_item
.ident
, sig
, None
), &sig
.decl
,
641 body
, trait_item
.span
, trait_item
.id
);
643 TypeTraitItem(ref bounds
, ref default) => {
644 walk_ty_param_bounds_helper(visitor
, bounds
);
645 walk_ty_opt(visitor
, default);
650 pub fn walk_impl_item
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, impl_item
: &'v ImplItem
) {
651 visitor
.visit_ident(impl_item
.span
, impl_item
.ident
);
652 for attr
in &impl_item
.attrs
{
653 visitor
.visit_attribute(attr
);
655 match impl_item
.node
{
656 ConstImplItem(ref ty
, ref expr
) => {
657 visitor
.visit_ty(ty
);
658 visitor
.visit_expr(expr
);
660 MethodImplItem(ref sig
, ref body
) => {
661 visitor
.visit_fn(FnKind
::Method(impl_item
.ident
, sig
, Some(impl_item
.vis
)), &sig
.decl
,
662 body
, impl_item
.span
, impl_item
.id
);
664 TypeImplItem(ref ty
) => {
665 visitor
.visit_ty(ty
);
667 MacImplItem(ref mac
) => {
668 visitor
.visit_mac(mac
);
673 pub fn walk_struct_def
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
674 struct_definition
: &'v StructDef
) {
675 for field
in &struct_definition
.fields
{
676 visitor
.visit_struct_field(field
)
680 pub fn walk_struct_field
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
681 struct_field
: &'v StructField
) {
682 if let NamedField(name
, _
) = struct_field
.node
.kind
{
683 visitor
.visit_ident(struct_field
.span
, name
);
686 visitor
.visit_ty(&*struct_field
.node
.ty
);
688 for attr
in &struct_field
.node
.attrs
{
689 visitor
.visit_attribute(attr
);
693 pub fn walk_block
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, block
: &'v Block
) {
694 for statement
in &block
.stmts
{
695 visitor
.visit_stmt(&**statement
)
697 walk_expr_opt(visitor
, &block
.expr
)
700 pub fn walk_stmt
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, statement
: &'v Stmt
) {
701 match statement
.node
{
702 StmtDecl(ref declaration
, _
) => visitor
.visit_decl(&**declaration
),
703 StmtExpr(ref expression
, _
) | StmtSemi(ref expression
, _
) => {
704 visitor
.visit_expr(&**expression
)
706 StmtMac(ref mac
, _
) => visitor
.visit_mac(&**mac
),
710 pub fn walk_decl
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, declaration
: &'v Decl
) {
711 match declaration
.node
{
712 DeclLocal(ref local
) => visitor
.visit_local(&**local
),
713 DeclItem(ref item
) => visitor
.visit_item(&**item
),
717 pub fn walk_expr_opt
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
718 optional_expression
: &'v Option
<P
<Expr
>>) {
719 match *optional_expression
{
721 Some(ref expression
) => visitor
.visit_expr(&**expression
),
725 pub fn walk_exprs
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, expressions
: &'v
[P
<Expr
>]) {
726 for expression
in expressions
{
727 visitor
.visit_expr(&**expression
)
731 pub fn walk_mac
<'v
, V
: Visitor
<'v
>>(_
: &mut V
, _
: &'v Mac
) {
735 pub fn walk_expr
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, expression
: &'v Expr
) {
736 match expression
.node
{
737 ExprBox(ref place
, ref subexpression
) => {
738 place
.as_ref().map(|e
|visitor
.visit_expr(&**e
));
739 visitor
.visit_expr(&**subexpression
)
741 ExprVec(ref subexpressions
) => {
742 walk_exprs(visitor
, subexpressions
)
744 ExprRepeat(ref element
, ref count
) => {
745 visitor
.visit_expr(&**element
);
746 visitor
.visit_expr(&**count
)
748 ExprStruct(ref path
, ref fields
, ref optional_base
) => {
749 visitor
.visit_path(path
, expression
.id
);
750 for field
in fields
{
751 visitor
.visit_expr(&*field
.expr
)
753 walk_expr_opt(visitor
, optional_base
)
755 ExprTup(ref subexpressions
) => {
756 for subexpression
in subexpressions
{
757 visitor
.visit_expr(&**subexpression
)
760 ExprCall(ref callee_expression
, ref arguments
) => {
761 for argument
in arguments
{
762 visitor
.visit_expr(&**argument
)
764 visitor
.visit_expr(&**callee_expression
)
766 ExprMethodCall(_
, ref types
, ref arguments
) => {
767 walk_exprs(visitor
, arguments
);
769 visitor
.visit_ty(&**typ
)
772 ExprBinary(_
, ref left_expression
, ref right_expression
) => {
773 visitor
.visit_expr(&**left_expression
);
774 visitor
.visit_expr(&**right_expression
)
776 ExprAddrOf(_
, ref subexpression
) | ExprUnary(_
, ref subexpression
) => {
777 visitor
.visit_expr(&**subexpression
)
780 ExprCast(ref subexpression
, ref typ
) => {
781 visitor
.visit_expr(&**subexpression
);
782 visitor
.visit_ty(&**typ
)
784 ExprIf(ref head_expression
, ref if_block
, ref optional_else
) => {
785 visitor
.visit_expr(&**head_expression
);
786 visitor
.visit_block(&**if_block
);
787 walk_expr_opt(visitor
, optional_else
)
789 ExprWhile(ref subexpression
, ref block
, _
) => {
790 visitor
.visit_expr(&**subexpression
);
791 visitor
.visit_block(&**block
)
793 ExprIfLet(ref pattern
, ref subexpression
, ref if_block
, ref optional_else
) => {
794 visitor
.visit_pat(&**pattern
);
795 visitor
.visit_expr(&**subexpression
);
796 visitor
.visit_block(&**if_block
);
797 walk_expr_opt(visitor
, optional_else
);
799 ExprWhileLet(ref pattern
, ref subexpression
, ref block
, _
) => {
800 visitor
.visit_pat(&**pattern
);
801 visitor
.visit_expr(&**subexpression
);
802 visitor
.visit_block(&**block
);
804 ExprForLoop(ref pattern
, ref subexpression
, ref block
, _
) => {
805 visitor
.visit_pat(&**pattern
);
806 visitor
.visit_expr(&**subexpression
);
807 visitor
.visit_block(&**block
)
809 ExprLoop(ref block
, _
) => visitor
.visit_block(&**block
),
810 ExprMatch(ref subexpression
, ref arms
, _
) => {
811 visitor
.visit_expr(&**subexpression
);
813 visitor
.visit_arm(arm
)
816 ExprClosure(_
, ref function_declaration
, ref body
) => {
817 visitor
.visit_fn(FnKind
::Closure
,
818 &**function_declaration
,
823 ExprBlock(ref block
) => visitor
.visit_block(&**block
),
824 ExprAssign(ref left_hand_expression
, ref right_hand_expression
) => {
825 visitor
.visit_expr(&**right_hand_expression
);
826 visitor
.visit_expr(&**left_hand_expression
)
828 ExprAssignOp(_
, ref left_expression
, ref right_expression
) => {
829 visitor
.visit_expr(&**right_expression
);
830 visitor
.visit_expr(&**left_expression
)
832 ExprField(ref subexpression
, _
) => {
833 visitor
.visit_expr(&**subexpression
);
835 ExprTupField(ref subexpression
, _
) => {
836 visitor
.visit_expr(&**subexpression
);
838 ExprIndex(ref main_expression
, ref index_expression
) => {
839 visitor
.visit_expr(&**main_expression
);
840 visitor
.visit_expr(&**index_expression
)
842 ExprRange(ref start
, ref end
) => {
843 walk_expr_opt(visitor
, start
);
844 walk_expr_opt(visitor
, end
)
846 ExprPath(ref maybe_qself
, ref path
) => {
847 if let Some(ref qself
) = *maybe_qself
{
848 visitor
.visit_ty(&qself
.ty
);
850 visitor
.visit_path(path
, expression
.id
)
852 ExprBreak(_
) | ExprAgain(_
) => {}
853 ExprRet(ref optional_expression
) => {
854 walk_expr_opt(visitor
, optional_expression
)
856 ExprMac(ref mac
) => visitor
.visit_mac(mac
),
857 ExprParen(ref subexpression
) => {
858 visitor
.visit_expr(&**subexpression
)
860 ExprInlineAsm(ref ia
) => {
861 for input
in &ia
.inputs
{
862 let (_
, ref input
) = *input
;
863 visitor
.visit_expr(&**input
)
865 for output
in &ia
.outputs
{
866 let (_
, ref output
, _
) = *output
;
867 visitor
.visit_expr(&**output
)
872 visitor
.visit_expr_post(expression
)
875 pub fn walk_arm
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, arm
: &'v Arm
) {
876 for pattern
in &arm
.pats
{
877 visitor
.visit_pat(&**pattern
)
879 walk_expr_opt(visitor
, &arm
.guard
);
880 visitor
.visit_expr(&*arm
.body
);
881 for attr
in &arm
.attrs
{
882 visitor
.visit_attribute(attr
);