1 // Copyright 2012-2015 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.
28 use attr
::ThinAttributesExt
;
31 #[derive(Copy, Clone, PartialEq, Eq)]
33 /// fn foo() or extern "Abi" fn foo()
34 ItemFn(Ident
, &'a Generics
, Unsafety
, Constness
, Abi
, Visibility
),
37 Method(Ident
, &'a MethodSig
, Option
<Visibility
>),
43 /// Each method of the Visitor trait is a hook to be potentially
44 /// overridden. Each method's default implementation recursively visits
45 /// the substructure of the input via the corresponding `walk` method;
46 /// e.g. the `visit_mod` method by default calls `visit::walk_mod`.
48 /// If you want to ensure that your code handles every variant
49 /// explicitly, you need to override each method. (And you also need
50 /// to monitor future changes to `Visitor` in case a new method with a
51 /// new default implementation gets introduced.)
52 pub trait Visitor
<'v
> : Sized
{
53 fn visit_name(&mut self, _span
: Span
, _name
: Name
) {
56 fn visit_ident(&mut self, span
: Span
, ident
: Ident
) {
57 walk_ident(self, span
, ident
);
59 fn visit_mod(&mut self, m
: &'v Mod
, _s
: Span
, _n
: NodeId
) { walk_mod(self, m) }
60 fn visit_foreign_item(&mut self, i
: &'v ForeignItem
) { walk_foreign_item(self, i) }
61 fn visit_item(&mut self, i
: &'v Item
) { walk_item(self, i) }
62 fn visit_local(&mut self, l
: &'v Local
) { walk_local(self, l) }
63 fn visit_block(&mut self, b
: &'v Block
) { walk_block(self, b) }
64 fn visit_stmt(&mut self, s
: &'v Stmt
) { walk_stmt(self, s) }
65 fn visit_arm(&mut self, a
: &'v Arm
) { walk_arm(self, a) }
66 fn visit_pat(&mut self, p
: &'v Pat
) { walk_pat(self, p) }
67 fn visit_decl(&mut self, d
: &'v Decl
) { walk_decl(self, d) }
68 fn visit_expr(&mut self, ex
: &'v Expr
) { walk_expr(self, ex) }
69 fn visit_expr_post(&mut self, _ex
: &'v Expr
) { }
70 fn visit_ty(&mut self, t
: &'v Ty
) { walk_ty(self, t) }
71 fn visit_generics(&mut self, g
: &'v Generics
) { walk_generics(self, g) }
72 fn visit_fn(&mut self, fk
: FnKind
<'v
>, fd
: &'v FnDecl
, b
: &'v Block
, s
: Span
, _
: NodeId
) {
73 walk_fn(self, fk
, fd
, b
, s
)
75 fn visit_trait_item(&mut self, ti
: &'v TraitItem
) { walk_trait_item(self, ti) }
76 fn visit_impl_item(&mut self, ii
: &'v ImplItem
) { walk_impl_item(self, ii) }
77 fn visit_trait_ref(&mut self, t
: &'v TraitRef
) { walk_trait_ref(self, t) }
78 fn visit_ty_param_bound(&mut self, bounds
: &'v TyParamBound
) {
79 walk_ty_param_bound(self, bounds
)
81 fn visit_poly_trait_ref(&mut self, t
: &'v PolyTraitRef
, m
: &'v TraitBoundModifier
) {
82 walk_poly_trait_ref(self, t
, m
)
84 fn visit_variant_data(&mut self, s
: &'v VariantData
, _
: Ident
,
85 _
: &'v Generics
, _
: NodeId
, _
: Span
) {
86 walk_struct_def(self, s
)
88 fn visit_struct_field(&mut self, s
: &'v StructField
) { walk_struct_field(self, s) }
89 fn visit_enum_def(&mut self, enum_definition
: &'v EnumDef
,
90 generics
: &'v Generics
, item_id
: NodeId
, _
: Span
) {
91 walk_enum_def(self, enum_definition
, generics
, item_id
)
93 fn visit_variant(&mut self, v
: &'v Variant
, g
: &'v Generics
, item_id
: NodeId
) {
94 walk_variant(self, v
, g
, item_id
)
96 fn visit_lifetime(&mut self, lifetime
: &'v Lifetime
) {
97 walk_lifetime(self, lifetime
)
99 fn visit_lifetime_def(&mut self, lifetime
: &'v LifetimeDef
) {
100 walk_lifetime_def(self, lifetime
)
102 fn visit_explicit_self(&mut self, es
: &'v ExplicitSelf
) {
103 walk_explicit_self(self, es
)
105 fn visit_mac(&mut self, _mac
: &'v Mac
) {
106 panic
!("visit_mac disabled by default");
107 // NB: see note about macros above.
108 // if you really want a visitor that
109 // works on macros, use this
110 // definition in your trait impl:
111 // visit::walk_mac(self, _mac)
113 fn visit_path(&mut self, path
: &'v Path
, _id
: NodeId
) {
114 walk_path(self, path
)
116 fn visit_path_list_item(&mut self, prefix
: &'v Path
, item
: &'v PathListItem
) {
117 walk_path_list_item(self, prefix
, item
)
119 fn visit_path_segment(&mut self, path_span
: Span
, path_segment
: &'v PathSegment
) {
120 walk_path_segment(self, path_span
, path_segment
)
122 fn visit_path_parameters(&mut self, path_span
: Span
, path_parameters
: &'v PathParameters
) {
123 walk_path_parameters(self, path_span
, path_parameters
)
125 fn visit_assoc_type_binding(&mut self, type_binding
: &'v TypeBinding
) {
126 walk_assoc_type_binding(self, type_binding
)
128 fn visit_attribute(&mut self, _attr
: &'v Attribute
) {}
129 fn visit_macro_def(&mut self, macro_def
: &'v MacroDef
) {
130 walk_macro_def(self, macro_def
)
135 macro_rules
! walk_list
{
136 ($visitor
: expr
, $method
: ident
, $list
: expr
) => {
138 $visitor
.$
method(elem
)
141 ($visitor
: expr
, $method
: ident
, $list
: expr
, $
($extra_args
: expr
),*) => {
143 $visitor
.$
method(elem
, $
($extra_args
,)*)
148 pub fn walk_opt_name
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, span
: Span
, opt_name
: Option
<Name
>) {
149 for name
in opt_name
{
150 visitor
.visit_name(span
, name
);
154 pub fn walk_opt_ident
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, span
: Span
, opt_ident
: Option
<Ident
>) {
155 for ident
in opt_ident
{
156 visitor
.visit_ident(span
, ident
);
160 pub fn walk_ident
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, span
: Span
, ident
: Ident
) {
161 visitor
.visit_name(span
, ident
.name
);
164 pub fn walk_crate
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, krate
: &'v Crate
) {
165 visitor
.visit_mod(&krate
.module
, krate
.span
, CRATE_NODE_ID
);
166 walk_list
!(visitor
, visit_attribute
, &krate
.attrs
);
167 walk_list
!(visitor
, visit_macro_def
, &krate
.exported_macros
);
170 pub fn walk_macro_def
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, macro_def
: &'v MacroDef
) {
171 visitor
.visit_ident(macro_def
.span
, macro_def
.ident
);
172 walk_opt_ident(visitor
, macro_def
.span
, macro_def
.imported_from
);
173 walk_list
!(visitor
, visit_attribute
, ¯o_def
.attrs
);
176 pub fn walk_mod
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, module
: &'v Mod
) {
177 walk_list
!(visitor
, visit_item
, &module
.items
);
180 pub fn walk_local
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, local
: &'v Local
) {
181 visitor
.visit_pat(&local
.pat
);
182 walk_list
!(visitor
, visit_ty
, &local
.ty
);
183 walk_list
!(visitor
, visit_expr
, &local
.init
);
186 pub fn walk_lifetime
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, lifetime
: &'v Lifetime
) {
187 visitor
.visit_name(lifetime
.span
, lifetime
.name
);
190 pub fn walk_lifetime_def
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
191 lifetime_def
: &'v LifetimeDef
) {
192 visitor
.visit_lifetime(&lifetime_def
.lifetime
);
193 walk_list
!(visitor
, visit_lifetime
, &lifetime_def
.bounds
);
196 pub fn walk_explicit_self
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
197 explicit_self
: &'v ExplicitSelf
) {
198 match explicit_self
.node
{
200 SelfValue(ident
) => {
201 visitor
.visit_ident(explicit_self
.span
, ident
)
203 SelfRegion(ref opt_lifetime
, _
, ident
) => {
204 visitor
.visit_ident(explicit_self
.span
, ident
);
205 walk_list
!(visitor
, visit_lifetime
, opt_lifetime
);
207 SelfExplicit(ref typ
, ident
) => {
208 visitor
.visit_ident(explicit_self
.span
, ident
);
209 visitor
.visit_ty(typ
)
214 pub fn walk_poly_trait_ref
<'v
, V
>(visitor
: &mut V
,
215 trait_ref
: &'v PolyTraitRef
,
216 _modifier
: &'v TraitBoundModifier
)
219 walk_list
!(visitor
, visit_lifetime_def
, &trait_ref
.bound_lifetimes
);
220 visitor
.visit_trait_ref(&trait_ref
.trait_ref
);
223 pub fn walk_trait_ref
<'v
,V
>(visitor
: &mut V
,
224 trait_ref
: &'v TraitRef
)
227 visitor
.visit_path(&trait_ref
.path
, trait_ref
.ref_id
)
230 pub fn walk_item
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, item
: &'v Item
) {
231 visitor
.visit_ident(item
.span
, item
.ident
);
233 ItemExternCrate(opt_name
) => {
234 walk_opt_name(visitor
, item
.span
, opt_name
)
238 ViewPathSimple(ident
, ref path
) => {
239 visitor
.visit_ident(vp
.span
, ident
);
240 visitor
.visit_path(path
, item
.id
);
242 ViewPathGlob(ref path
) => {
243 visitor
.visit_path(path
, item
.id
);
245 ViewPathList(ref prefix
, ref list
) => {
246 if !list
.is_empty() {
248 visitor
.visit_path_list_item(prefix
, item
)
251 visitor
.visit_path(prefix
, item
.id
);
256 ItemStatic(ref typ
, _
, ref expr
) |
257 ItemConst(ref typ
, ref expr
) => {
258 visitor
.visit_ty(typ
);
259 visitor
.visit_expr(expr
);
261 ItemFn(ref declaration
, unsafety
, constness
, abi
, ref generics
, ref body
) => {
262 visitor
.visit_fn(FnKind
::ItemFn(item
.ident
, generics
, unsafety
,
263 constness
, abi
, item
.vis
),
269 ItemMod(ref module
) => {
270 visitor
.visit_mod(module
, item
.span
, item
.id
)
272 ItemForeignMod(ref foreign_module
) => {
273 walk_list
!(visitor
, visit_foreign_item
, &foreign_module
.items
);
275 ItemTy(ref typ
, ref type_parameters
) => {
276 visitor
.visit_ty(typ
);
277 visitor
.visit_generics(type_parameters
)
279 ItemEnum(ref enum_definition
, ref type_parameters
) => {
280 visitor
.visit_generics(type_parameters
);
281 visitor
.visit_enum_def(enum_definition
, type_parameters
, item
.id
, item
.span
)
283 ItemDefaultImpl(_
, ref trait_ref
) => {
284 visitor
.visit_trait_ref(trait_ref
)
288 ref opt_trait_reference
,
291 visitor
.visit_generics(type_parameters
);
292 walk_list
!(visitor
, visit_trait_ref
, opt_trait_reference
);
293 visitor
.visit_ty(typ
);
294 walk_list
!(visitor
, visit_impl_item
, impl_items
);
296 ItemStruct(ref struct_definition
, ref generics
) => {
297 visitor
.visit_generics(generics
);
298 visitor
.visit_variant_data(struct_definition
, item
.ident
,
299 generics
, item
.id
, item
.span
);
301 ItemTrait(_
, ref generics
, ref bounds
, ref methods
) => {
302 visitor
.visit_generics(generics
);
303 walk_list
!(visitor
, visit_ty_param_bound
, bounds
);
304 walk_list
!(visitor
, visit_trait_item
, methods
);
306 ItemMac(ref mac
) => visitor
.visit_mac(mac
),
308 walk_list
!(visitor
, visit_attribute
, &item
.attrs
);
311 pub fn walk_enum_def
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
312 enum_definition
: &'v EnumDef
,
313 generics
: &'v Generics
,
315 walk_list
!(visitor
, visit_variant
, &enum_definition
.variants
, generics
, item_id
);
318 pub fn walk_variant
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
319 variant
: &'v Variant
,
320 generics
: &'v Generics
,
322 visitor
.visit_ident(variant
.span
, variant
.node
.name
);
323 visitor
.visit_variant_data(&variant
.node
.data
, variant
.node
.name
,
324 generics
, item_id
, variant
.span
);
325 walk_list
!(visitor
, visit_expr
, &variant
.node
.disr_expr
);
326 walk_list
!(visitor
, visit_attribute
, &variant
.node
.attrs
);
329 pub fn walk_ty
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, typ
: &'v Ty
) {
331 TyVec(ref ty
) | TyParen(ref ty
) => {
334 TyPtr(ref mutable_type
) => {
335 visitor
.visit_ty(&mutable_type
.ty
)
337 TyRptr(ref opt_lifetime
, ref mutable_type
) => {
338 walk_list
!(visitor
, visit_lifetime
, opt_lifetime
);
339 visitor
.visit_ty(&mutable_type
.ty
)
341 TyTup(ref tuple_element_types
) => {
342 walk_list
!(visitor
, visit_ty
, tuple_element_types
);
344 TyBareFn(ref function_declaration
) => {
345 walk_fn_decl(visitor
, &function_declaration
.decl
);
346 walk_list
!(visitor
, visit_lifetime_def
, &function_declaration
.lifetimes
);
348 TyPath(ref maybe_qself
, ref path
) => {
349 if let Some(ref qself
) = *maybe_qself
{
350 visitor
.visit_ty(&qself
.ty
);
352 visitor
.visit_path(path
, typ
.id
);
354 TyObjectSum(ref ty
, ref bounds
) => {
355 visitor
.visit_ty(ty
);
356 walk_list
!(visitor
, visit_ty_param_bound
, bounds
);
358 TyFixedLengthVec(ref ty
, ref expression
) => {
359 visitor
.visit_ty(ty
);
360 visitor
.visit_expr(expression
)
362 TyPolyTraitRef(ref bounds
) => {
363 walk_list
!(visitor
, visit_ty_param_bound
, bounds
);
365 TyTypeof(ref expression
) => {
366 visitor
.visit_expr(expression
)
370 visitor
.visit_mac(mac
)
375 pub fn walk_path
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, path
: &'v Path
) {
376 for segment
in &path
.segments
{
377 visitor
.visit_path_segment(path
.span
, segment
);
381 pub fn walk_path_list_item
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, prefix
: &'v Path
,
382 item
: &'v PathListItem
) {
383 for segment
in &prefix
.segments
{
384 visitor
.visit_path_segment(prefix
.span
, segment
);
387 walk_opt_ident(visitor
, item
.span
, item
.node
.name());
388 walk_opt_ident(visitor
, item
.span
, item
.node
.rename());
391 pub fn walk_path_segment
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
393 segment
: &'v PathSegment
) {
394 visitor
.visit_ident(path_span
, segment
.identifier
);
395 visitor
.visit_path_parameters(path_span
, &segment
.parameters
);
398 pub fn walk_path_parameters
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
400 path_parameters
: &'v PathParameters
) {
401 match *path_parameters
{
402 AngleBracketedParameters(ref data
) => {
403 walk_list
!(visitor
, visit_ty
, &data
.types
);
404 walk_list
!(visitor
, visit_lifetime
, &data
.lifetimes
);
405 walk_list
!(visitor
, visit_assoc_type_binding
, &data
.bindings
);
407 ParenthesizedParameters(ref data
) => {
408 walk_list
!(visitor
, visit_ty
, &data
.inputs
);
409 walk_list
!(visitor
, visit_ty
, &data
.output
);
414 pub fn walk_assoc_type_binding
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
415 type_binding
: &'v TypeBinding
) {
416 visitor
.visit_ident(type_binding
.span
, type_binding
.ident
);
417 visitor
.visit_ty(&type_binding
.ty
);
420 pub fn walk_pat
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, pattern
: &'v Pat
) {
422 PatEnum(ref path
, ref opt_children
) => {
423 visitor
.visit_path(path
, pattern
.id
);
424 if let Some(ref children
) = *opt_children
{
425 walk_list
!(visitor
, visit_pat
, children
);
428 PatQPath(ref qself
, ref path
) => {
429 visitor
.visit_ty(&qself
.ty
);
430 visitor
.visit_path(path
, pattern
.id
)
432 PatStruct(ref path
, ref fields
, _
) => {
433 visitor
.visit_path(path
, pattern
.id
);
434 for field
in fields
{
435 visitor
.visit_ident(field
.span
, field
.node
.ident
);
436 visitor
.visit_pat(&field
.node
.pat
)
439 PatTup(ref tuple_elements
) => {
440 walk_list
!(visitor
, visit_pat
, tuple_elements
);
442 PatBox(ref subpattern
) |
443 PatRegion(ref subpattern
, _
) => {
444 visitor
.visit_pat(subpattern
)
446 PatIdent(_
, ref pth1
, ref optional_subpattern
) => {
447 visitor
.visit_ident(pth1
.span
, pth1
.node
);
448 walk_list
!(visitor
, visit_pat
, optional_subpattern
);
450 PatLit(ref expression
) => visitor
.visit_expr(expression
),
451 PatRange(ref lower_bound
, ref upper_bound
) => {
452 visitor
.visit_expr(lower_bound
);
453 visitor
.visit_expr(upper_bound
)
456 PatVec(ref prepatterns
, ref slice_pattern
, ref postpatterns
) => {
457 walk_list
!(visitor
, visit_pat
, prepatterns
);
458 walk_list
!(visitor
, visit_pat
, slice_pattern
);
459 walk_list
!(visitor
, visit_pat
, postpatterns
);
461 PatMac(ref mac
) => visitor
.visit_mac(mac
),
465 pub fn walk_foreign_item
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
466 foreign_item
: &'v ForeignItem
) {
467 visitor
.visit_ident(foreign_item
.span
, foreign_item
.ident
);
469 match foreign_item
.node
{
470 ForeignItemFn(ref function_declaration
, ref generics
) => {
471 walk_fn_decl(visitor
, function_declaration
);
472 visitor
.visit_generics(generics
)
474 ForeignItemStatic(ref typ
, _
) => visitor
.visit_ty(typ
),
477 walk_list
!(visitor
, visit_attribute
, &foreign_item
.attrs
);
480 pub fn walk_ty_param_bound
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
481 bound
: &'v TyParamBound
) {
483 TraitTyParamBound(ref typ
, ref modifier
) => {
484 visitor
.visit_poly_trait_ref(typ
, modifier
);
486 RegionTyParamBound(ref lifetime
) => {
487 visitor
.visit_lifetime(lifetime
);
492 pub fn walk_generics
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, generics
: &'v Generics
) {
493 for param
in &generics
.ty_params
{
494 visitor
.visit_ident(param
.span
, param
.ident
);
495 walk_list
!(visitor
, visit_ty_param_bound
, ¶m
.bounds
);
496 walk_list
!(visitor
, visit_ty
, ¶m
.default);
498 walk_list
!(visitor
, visit_lifetime_def
, &generics
.lifetimes
);
499 for predicate
in &generics
.where_clause
.predicates
{
501 WherePredicate
::BoundPredicate(WhereBoundPredicate
{ref bounded_ty
,
505 visitor
.visit_ty(bounded_ty
);
506 walk_list
!(visitor
, visit_ty_param_bound
, bounds
);
507 walk_list
!(visitor
, visit_lifetime_def
, bound_lifetimes
);
509 WherePredicate
::RegionPredicate(WhereRegionPredicate
{ref lifetime
,
512 visitor
.visit_lifetime(lifetime
);
513 walk_list
!(visitor
, visit_lifetime
, bounds
);
515 WherePredicate
::EqPredicate(WhereEqPredicate
{id
,
519 visitor
.visit_path(path
, id
);
520 visitor
.visit_ty(ty
);
526 pub fn walk_fn_ret_ty
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, ret_ty
: &'v FunctionRetTy
) {
527 if let Return(ref output_ty
) = *ret_ty
{
528 visitor
.visit_ty(output_ty
)
532 pub fn walk_fn_decl
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, function_declaration
: &'v FnDecl
) {
533 for argument
in &function_declaration
.inputs
{
534 visitor
.visit_pat(&argument
.pat
);
535 visitor
.visit_ty(&argument
.ty
)
537 walk_fn_ret_ty(visitor
, &function_declaration
.output
)
540 pub fn walk_fn_kind
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
541 function_kind
: FnKind
<'v
>) {
542 match function_kind
{
543 FnKind
::ItemFn(_
, generics
, _
, _
, _
, _
) => {
544 visitor
.visit_generics(generics
);
546 FnKind
::Method(_
, sig
, _
) => {
547 visitor
.visit_generics(&sig
.generics
);
548 visitor
.visit_explicit_self(&sig
.explicit_self
);
550 FnKind
::Closure
=> {}
554 pub fn walk_fn
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
555 function_kind
: FnKind
<'v
>,
556 function_declaration
: &'v FnDecl
,
557 function_body
: &'v Block
,
559 walk_fn_decl(visitor
, function_declaration
);
560 walk_fn_kind(visitor
, function_kind
);
561 visitor
.visit_block(function_body
)
564 pub fn walk_trait_item
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, trait_item
: &'v TraitItem
) {
565 visitor
.visit_ident(trait_item
.span
, trait_item
.ident
);
566 walk_list
!(visitor
, visit_attribute
, &trait_item
.attrs
);
567 match trait_item
.node
{
568 ConstTraitItem(ref ty
, ref default) => {
569 visitor
.visit_ty(ty
);
570 walk_list
!(visitor
, visit_expr
, default);
572 MethodTraitItem(ref sig
, None
) => {
573 visitor
.visit_explicit_self(&sig
.explicit_self
);
574 visitor
.visit_generics(&sig
.generics
);
575 walk_fn_decl(visitor
, &sig
.decl
);
577 MethodTraitItem(ref sig
, Some(ref body
)) => {
578 visitor
.visit_fn(FnKind
::Method(trait_item
.ident
, sig
, None
), &sig
.decl
,
579 body
, trait_item
.span
, trait_item
.id
);
581 TypeTraitItem(ref bounds
, ref default) => {
582 walk_list
!(visitor
, visit_ty_param_bound
, bounds
);
583 walk_list
!(visitor
, visit_ty
, default);
588 pub fn walk_impl_item
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, impl_item
: &'v ImplItem
) {
589 visitor
.visit_ident(impl_item
.span
, impl_item
.ident
);
590 walk_list
!(visitor
, visit_attribute
, &impl_item
.attrs
);
591 match impl_item
.node
{
592 ImplItemKind
::Const(ref ty
, ref expr
) => {
593 visitor
.visit_ty(ty
);
594 visitor
.visit_expr(expr
);
596 ImplItemKind
::Method(ref sig
, ref body
) => {
597 visitor
.visit_fn(FnKind
::Method(impl_item
.ident
, sig
, Some(impl_item
.vis
)), &sig
.decl
,
598 body
, impl_item
.span
, impl_item
.id
);
600 ImplItemKind
::Type(ref ty
) => {
601 visitor
.visit_ty(ty
);
603 ImplItemKind
::Macro(ref mac
) => {
604 visitor
.visit_mac(mac
);
609 pub fn walk_struct_def
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
610 struct_definition
: &'v VariantData
) {
611 walk_list
!(visitor
, visit_struct_field
, struct_definition
.fields());
614 pub fn walk_struct_field
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
,
615 struct_field
: &'v StructField
) {
616 walk_opt_ident(visitor
, struct_field
.span
, struct_field
.node
.ident());
617 visitor
.visit_ty(&struct_field
.node
.ty
);
618 walk_list
!(visitor
, visit_attribute
, &struct_field
.node
.attrs
);
621 pub fn walk_block
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, block
: &'v Block
) {
622 walk_list
!(visitor
, visit_stmt
, &block
.stmts
);
623 walk_list
!(visitor
, visit_expr
, &block
.expr
);
626 pub fn walk_stmt
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, statement
: &'v Stmt
) {
627 match statement
.node
{
628 StmtDecl(ref declaration
, _
) => visitor
.visit_decl(declaration
),
629 StmtExpr(ref expression
, _
) | StmtSemi(ref expression
, _
) => {
630 visitor
.visit_expr(expression
)
632 StmtMac(ref mac
, _
, ref attrs
) => {
633 visitor
.visit_mac(mac
);
634 for attr
in attrs
.as_attr_slice() {
635 visitor
.visit_attribute(attr
);
641 pub fn walk_decl
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, declaration
: &'v Decl
) {
642 match declaration
.node
{
643 DeclLocal(ref local
) => visitor
.visit_local(local
),
644 DeclItem(ref item
) => visitor
.visit_item(item
),
648 pub fn walk_mac
<'v
, V
: Visitor
<'v
>>(_
: &mut V
, _
: &'v Mac
) {
652 pub fn walk_expr
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, expression
: &'v Expr
) {
653 match expression
.node
{
654 ExprBox(ref subexpression
) => {
655 visitor
.visit_expr(subexpression
)
657 ExprInPlace(ref place
, ref subexpression
) => {
658 visitor
.visit_expr(place
);
659 visitor
.visit_expr(subexpression
)
661 ExprVec(ref subexpressions
) => {
662 walk_list
!(visitor
, visit_expr
, subexpressions
);
664 ExprRepeat(ref element
, ref count
) => {
665 visitor
.visit_expr(element
);
666 visitor
.visit_expr(count
)
668 ExprStruct(ref path
, ref fields
, ref optional_base
) => {
669 visitor
.visit_path(path
, expression
.id
);
670 for field
in fields
{
671 visitor
.visit_ident(field
.ident
.span
, field
.ident
.node
);
672 visitor
.visit_expr(&field
.expr
)
674 walk_list
!(visitor
, visit_expr
, optional_base
);
676 ExprTup(ref subexpressions
) => {
677 walk_list
!(visitor
, visit_expr
, subexpressions
);
679 ExprCall(ref callee_expression
, ref arguments
) => {
680 walk_list
!(visitor
, visit_expr
, arguments
);
681 visitor
.visit_expr(callee_expression
)
683 ExprMethodCall(ref ident
, ref types
, ref arguments
) => {
684 visitor
.visit_ident(ident
.span
, ident
.node
);
685 walk_list
!(visitor
, visit_expr
, arguments
);
686 walk_list
!(visitor
, visit_ty
, types
);
688 ExprBinary(_
, ref left_expression
, ref right_expression
) => {
689 visitor
.visit_expr(left_expression
);
690 visitor
.visit_expr(right_expression
)
692 ExprAddrOf(_
, ref subexpression
) | ExprUnary(_
, ref subexpression
) => {
693 visitor
.visit_expr(subexpression
)
696 ExprCast(ref subexpression
, ref typ
) => {
697 visitor
.visit_expr(subexpression
);
698 visitor
.visit_ty(typ
)
700 ExprIf(ref head_expression
, ref if_block
, ref optional_else
) => {
701 visitor
.visit_expr(head_expression
);
702 visitor
.visit_block(if_block
);
703 walk_list
!(visitor
, visit_expr
, optional_else
);
705 ExprWhile(ref subexpression
, ref block
, opt_ident
) => {
706 visitor
.visit_expr(subexpression
);
707 visitor
.visit_block(block
);
708 walk_opt_ident(visitor
, expression
.span
, opt_ident
)
710 ExprIfLet(ref pattern
, ref subexpression
, ref if_block
, ref optional_else
) => {
711 visitor
.visit_pat(pattern
);
712 visitor
.visit_expr(subexpression
);
713 visitor
.visit_block(if_block
);
714 walk_list
!(visitor
, visit_expr
, optional_else
);
716 ExprWhileLet(ref pattern
, ref subexpression
, ref block
, opt_ident
) => {
717 visitor
.visit_pat(pattern
);
718 visitor
.visit_expr(subexpression
);
719 visitor
.visit_block(block
);
720 walk_opt_ident(visitor
, expression
.span
, opt_ident
)
722 ExprForLoop(ref pattern
, ref subexpression
, ref block
, opt_ident
) => {
723 visitor
.visit_pat(pattern
);
724 visitor
.visit_expr(subexpression
);
725 visitor
.visit_block(block
);
726 walk_opt_ident(visitor
, expression
.span
, opt_ident
)
728 ExprLoop(ref block
, opt_ident
) => {
729 visitor
.visit_block(block
);
730 walk_opt_ident(visitor
, expression
.span
, opt_ident
)
732 ExprMatch(ref subexpression
, ref arms
) => {
733 visitor
.visit_expr(subexpression
);
734 walk_list
!(visitor
, visit_arm
, arms
);
736 ExprClosure(_
, ref function_declaration
, ref body
) => {
737 visitor
.visit_fn(FnKind
::Closure
,
738 function_declaration
,
743 ExprBlock(ref block
) => visitor
.visit_block(block
),
744 ExprAssign(ref left_hand_expression
, ref right_hand_expression
) => {
745 visitor
.visit_expr(right_hand_expression
);
746 visitor
.visit_expr(left_hand_expression
)
748 ExprAssignOp(_
, ref left_expression
, ref right_expression
) => {
749 visitor
.visit_expr(right_expression
);
750 visitor
.visit_expr(left_expression
)
752 ExprField(ref subexpression
, ref ident
) => {
753 visitor
.visit_expr(subexpression
);
754 visitor
.visit_ident(ident
.span
, ident
.node
);
756 ExprTupField(ref subexpression
, _
) => {
757 visitor
.visit_expr(subexpression
);
759 ExprIndex(ref main_expression
, ref index_expression
) => {
760 visitor
.visit_expr(main_expression
);
761 visitor
.visit_expr(index_expression
)
763 ExprRange(ref start
, ref end
) => {
764 walk_list
!(visitor
, visit_expr
, start
);
765 walk_list
!(visitor
, visit_expr
, end
);
767 ExprPath(ref maybe_qself
, ref path
) => {
768 if let Some(ref qself
) = *maybe_qself
{
769 visitor
.visit_ty(&qself
.ty
);
771 visitor
.visit_path(path
, expression
.id
)
773 ExprBreak(ref opt_sp_ident
) | ExprAgain(ref opt_sp_ident
) => {
774 for sp_ident
in opt_sp_ident
{
775 visitor
.visit_ident(sp_ident
.span
, sp_ident
.node
);
778 ExprRet(ref optional_expression
) => {
779 walk_list
!(visitor
, visit_expr
, optional_expression
);
781 ExprMac(ref mac
) => visitor
.visit_mac(mac
),
782 ExprParen(ref subexpression
) => {
783 visitor
.visit_expr(subexpression
)
785 ExprInlineAsm(ref ia
) => {
786 for &(_
, ref input
) in &ia
.inputs
{
787 visitor
.visit_expr(&input
)
789 for &(_
, ref output
, _
) in &ia
.outputs
{
790 visitor
.visit_expr(&output
)
795 visitor
.visit_expr_post(expression
)
798 pub fn walk_arm
<'v
, V
: Visitor
<'v
>>(visitor
: &mut V
, arm
: &'v Arm
) {
799 walk_list
!(visitor
, visit_pat
, &arm
.pats
);
800 walk_list
!(visitor
, visit_expr
, &arm
.guard
);
801 visitor
.visit_expr(&arm
.body
);
802 walk_list
!(visitor
, visit_attribute
, &arm
.attrs
);