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.
31 #[derive(Copy, Clone, PartialEq, Eq)]
33 /// fn foo() or extern "Abi" fn foo()
34 ItemFn(Ident
, &'a Generics
, Unsafety
, Spanned
<Constness
>, Abi
, &'a Visibility
),
37 Method(Ident
, &'a MethodSig
, Option
<&'a 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
: 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
: &Mod
, _s
: Span
, _n
: NodeId
) { walk_mod(self, m) }
60 fn visit_foreign_item(&mut self, i
: &ForeignItem
) { walk_foreign_item(self, i) }
61 fn visit_item(&mut self, i
: &Item
) { walk_item(self, i) }
62 fn visit_local(&mut self, l
: &Local
) { walk_local(self, l) }
63 fn visit_block(&mut self, b
: &Block
) { walk_block(self, b) }
64 fn visit_stmt(&mut self, s
: &Stmt
) { walk_stmt(self, s) }
65 fn visit_arm(&mut self, a
: &Arm
) { walk_arm(self, a) }
66 fn visit_pat(&mut self, p
: &Pat
) { walk_pat(self, p) }
67 fn visit_expr(&mut self, ex
: &Expr
) { walk_expr(self, ex) }
68 fn visit_expr_post(&mut self, _ex
: &Expr
) { }
69 fn visit_ty(&mut self, t
: &Ty
) { walk_ty(self, t) }
70 fn visit_generics(&mut self, g
: &Generics
) { walk_generics(self, g) }
71 fn visit_fn(&mut self, fk
: FnKind
, fd
: &FnDecl
, b
: &Block
, s
: Span
, _
: NodeId
) {
72 walk_fn(self, fk
, fd
, b
, s
)
74 fn visit_trait_item(&mut self, ti
: &TraitItem
) { walk_trait_item(self, ti) }
75 fn visit_impl_item(&mut self, ii
: &ImplItem
) { walk_impl_item(self, ii) }
76 fn visit_trait_ref(&mut self, t
: &TraitRef
) { walk_trait_ref(self, t) }
77 fn visit_ty_param_bound(&mut self, bounds
: &TyParamBound
) {
78 walk_ty_param_bound(self, bounds
)
80 fn visit_poly_trait_ref(&mut self, t
: &PolyTraitRef
, m
: &TraitBoundModifier
) {
81 walk_poly_trait_ref(self, t
, m
)
83 fn visit_variant_data(&mut self, s
: &VariantData
, _
: Ident
,
84 _
: &Generics
, _
: NodeId
, _
: Span
) {
85 walk_struct_def(self, s
)
87 fn visit_struct_field(&mut self, s
: &StructField
) { walk_struct_field(self, s) }
88 fn visit_enum_def(&mut self, enum_definition
: &EnumDef
,
89 generics
: &Generics
, item_id
: NodeId
, _
: Span
) {
90 walk_enum_def(self, enum_definition
, generics
, item_id
)
92 fn visit_variant(&mut self, v
: &Variant
, g
: &Generics
, item_id
: NodeId
) {
93 walk_variant(self, v
, g
, item_id
)
95 fn visit_lifetime(&mut self, lifetime
: &Lifetime
) {
96 walk_lifetime(self, lifetime
)
98 fn visit_lifetime_def(&mut self, lifetime
: &LifetimeDef
) {
99 walk_lifetime_def(self, lifetime
)
101 fn visit_mac(&mut self, _mac
: &Mac
) {
102 panic
!("visit_mac disabled by default");
103 // NB: see note about macros above.
104 // if you really want a visitor that
105 // works on macros, use this
106 // definition in your trait impl:
107 // visit::walk_mac(self, _mac)
109 fn visit_path(&mut self, path
: &Path
, _id
: NodeId
) {
110 walk_path(self, path
)
112 fn visit_path_list_item(&mut self, prefix
: &Path
, item
: &PathListItem
) {
113 walk_path_list_item(self, prefix
, item
)
115 fn visit_path_segment(&mut self, path_span
: Span
, path_segment
: &PathSegment
) {
116 walk_path_segment(self, path_span
, path_segment
)
118 fn visit_path_parameters(&mut self, path_span
: Span
, path_parameters
: &PathParameters
) {
119 walk_path_parameters(self, path_span
, path_parameters
)
121 fn visit_assoc_type_binding(&mut self, type_binding
: &TypeBinding
) {
122 walk_assoc_type_binding(self, type_binding
)
124 fn visit_attribute(&mut self, _attr
: &Attribute
) {}
125 fn visit_macro_def(&mut self, macro_def
: &MacroDef
) {
126 walk_macro_def(self, macro_def
)
128 fn visit_vis(&mut self, vis
: &Visibility
) {
131 fn visit_fn_ret_ty(&mut self, ret_ty
: &FunctionRetTy
) {
132 walk_fn_ret_ty(self, ret_ty
)
137 macro_rules
! walk_list
{
138 ($visitor
: expr
, $method
: ident
, $list
: expr
) => {
140 $visitor
.$
method(elem
)
143 ($visitor
: expr
, $method
: ident
, $list
: expr
, $
($extra_args
: expr
),*) => {
145 $visitor
.$
method(elem
, $
($extra_args
,)*)
150 pub fn walk_opt_name
<V
: Visitor
>(visitor
: &mut V
, span
: Span
, opt_name
: Option
<Name
>) {
151 if let Some(name
) = opt_name
{
152 visitor
.visit_name(span
, name
);
156 pub fn walk_opt_ident
<V
: Visitor
>(visitor
: &mut V
, span
: Span
, opt_ident
: Option
<Ident
>) {
157 if let Some(ident
) = opt_ident
{
158 visitor
.visit_ident(span
, ident
);
162 pub fn walk_opt_sp_ident
<V
: Visitor
>(visitor
: &mut V
, opt_sp_ident
: &Option
<Spanned
<Ident
>>) {
163 if let Some(ref sp_ident
) = *opt_sp_ident
{
164 visitor
.visit_ident(sp_ident
.span
, sp_ident
.node
);
168 pub fn walk_ident
<V
: Visitor
>(visitor
: &mut V
, span
: Span
, ident
: Ident
) {
169 visitor
.visit_name(span
, ident
.name
);
172 pub fn walk_crate
<V
: Visitor
>(visitor
: &mut V
, krate
: &Crate
) {
173 visitor
.visit_mod(&krate
.module
, krate
.span
, CRATE_NODE_ID
);
174 walk_list
!(visitor
, visit_attribute
, &krate
.attrs
);
175 walk_list
!(visitor
, visit_macro_def
, &krate
.exported_macros
);
178 pub fn walk_macro_def
<V
: Visitor
>(visitor
: &mut V
, macro_def
: &MacroDef
) {
179 visitor
.visit_ident(macro_def
.span
, macro_def
.ident
);
180 walk_opt_ident(visitor
, macro_def
.span
, macro_def
.imported_from
);
181 walk_list
!(visitor
, visit_attribute
, ¯o_def
.attrs
);
184 pub fn walk_mod
<V
: Visitor
>(visitor
: &mut V
, module
: &Mod
) {
185 walk_list
!(visitor
, visit_item
, &module
.items
);
188 pub fn walk_local
<V
: Visitor
>(visitor
: &mut V
, local
: &Local
) {
189 for attr
in local
.attrs
.iter() {
190 visitor
.visit_attribute(attr
);
192 visitor
.visit_pat(&local
.pat
);
193 walk_list
!(visitor
, visit_ty
, &local
.ty
);
194 walk_list
!(visitor
, visit_expr
, &local
.init
);
197 pub fn walk_lifetime
<V
: Visitor
>(visitor
: &mut V
, lifetime
: &Lifetime
) {
198 visitor
.visit_name(lifetime
.span
, lifetime
.name
);
201 pub fn walk_lifetime_def
<V
: Visitor
>(visitor
: &mut V
, lifetime_def
: &LifetimeDef
) {
202 visitor
.visit_lifetime(&lifetime_def
.lifetime
);
203 walk_list
!(visitor
, visit_lifetime
, &lifetime_def
.bounds
);
204 walk_list
!(visitor
, visit_attribute
, &*lifetime_def
.attrs
);
207 pub fn walk_poly_trait_ref
<V
>(visitor
: &mut V
, trait_ref
: &PolyTraitRef
, _
: &TraitBoundModifier
)
210 walk_list
!(visitor
, visit_lifetime_def
, &trait_ref
.bound_lifetimes
);
211 visitor
.visit_trait_ref(&trait_ref
.trait_ref
);
214 pub fn walk_trait_ref
<V
: Visitor
>(visitor
: &mut V
, trait_ref
: &TraitRef
) {
215 visitor
.visit_path(&trait_ref
.path
, trait_ref
.ref_id
)
218 pub fn walk_item
<V
: Visitor
>(visitor
: &mut V
, item
: &Item
) {
219 visitor
.visit_vis(&item
.vis
);
220 visitor
.visit_ident(item
.span
, item
.ident
);
222 ItemKind
::ExternCrate(opt_name
) => {
223 walk_opt_name(visitor
, item
.span
, opt_name
)
225 ItemKind
::Use(ref vp
) => {
227 ViewPathSimple(ident
, ref path
) => {
228 visitor
.visit_ident(vp
.span
, ident
);
229 visitor
.visit_path(path
, item
.id
);
231 ViewPathGlob(ref path
) => {
232 visitor
.visit_path(path
, item
.id
);
234 ViewPathList(ref prefix
, ref list
) => {
235 visitor
.visit_path(prefix
, item
.id
);
237 visitor
.visit_path_list_item(prefix
, item
)
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
, unsafety
, constness
, abi
, ref generics
, ref body
) => {
248 visitor
.visit_fn(FnKind
::ItemFn(item
.ident
, generics
, unsafety
,
249 constness
, abi
, &item
.vis
),
255 ItemKind
::Mod(ref module
) => {
256 visitor
.visit_mod(module
, item
.span
, item
.id
)
258 ItemKind
::ForeignMod(ref foreign_module
) => {
259 walk_list
!(visitor
, visit_foreign_item
, &foreign_module
.items
);
261 ItemKind
::Ty(ref typ
, ref type_parameters
) => {
262 visitor
.visit_ty(typ
);
263 visitor
.visit_generics(type_parameters
)
265 ItemKind
::Enum(ref enum_definition
, ref type_parameters
) => {
266 visitor
.visit_generics(type_parameters
);
267 visitor
.visit_enum_def(enum_definition
, type_parameters
, item
.id
, item
.span
)
269 ItemKind
::DefaultImpl(_
, ref trait_ref
) => {
270 visitor
.visit_trait_ref(trait_ref
)
274 ref opt_trait_reference
,
277 visitor
.visit_generics(type_parameters
);
278 walk_list
!(visitor
, visit_trait_ref
, opt_trait_reference
);
279 visitor
.visit_ty(typ
);
280 walk_list
!(visitor
, visit_impl_item
, impl_items
);
282 ItemKind
::Struct(ref struct_definition
, ref generics
) |
283 ItemKind
::Union(ref struct_definition
, ref generics
) => {
284 visitor
.visit_generics(generics
);
285 visitor
.visit_variant_data(struct_definition
, item
.ident
,
286 generics
, item
.id
, item
.span
);
288 ItemKind
::Trait(_
, ref generics
, ref bounds
, ref methods
) => {
289 visitor
.visit_generics(generics
);
290 walk_list
!(visitor
, visit_ty_param_bound
, bounds
);
291 walk_list
!(visitor
, visit_trait_item
, methods
);
293 ItemKind
::Mac(ref mac
) => visitor
.visit_mac(mac
),
295 walk_list
!(visitor
, visit_attribute
, &item
.attrs
);
298 pub fn walk_enum_def
<V
: Visitor
>(visitor
: &mut V
,
299 enum_definition
: &EnumDef
,
302 walk_list
!(visitor
, visit_variant
, &enum_definition
.variants
, generics
, item_id
);
305 pub fn walk_variant
<V
>(visitor
: &mut V
, variant
: &Variant
, generics
: &Generics
, item_id
: NodeId
)
308 visitor
.visit_ident(variant
.span
, variant
.node
.name
);
309 visitor
.visit_variant_data(&variant
.node
.data
, variant
.node
.name
,
310 generics
, item_id
, variant
.span
);
311 walk_list
!(visitor
, visit_expr
, &variant
.node
.disr_expr
);
312 walk_list
!(visitor
, visit_attribute
, &variant
.node
.attrs
);
315 pub fn walk_ty
<V
: Visitor
>(visitor
: &mut V
, typ
: &Ty
) {
317 TyKind
::Slice(ref ty
) | TyKind
::Paren(ref ty
) => {
320 TyKind
::Ptr(ref mutable_type
) => {
321 visitor
.visit_ty(&mutable_type
.ty
)
323 TyKind
::Rptr(ref opt_lifetime
, ref mutable_type
) => {
324 walk_list
!(visitor
, visit_lifetime
, opt_lifetime
);
325 visitor
.visit_ty(&mutable_type
.ty
)
328 TyKind
::Tup(ref tuple_element_types
) => {
329 walk_list
!(visitor
, visit_ty
, tuple_element_types
);
331 TyKind
::BareFn(ref function_declaration
) => {
332 walk_fn_decl(visitor
, &function_declaration
.decl
);
333 walk_list
!(visitor
, visit_lifetime_def
, &function_declaration
.lifetimes
);
335 TyKind
::Path(ref maybe_qself
, ref path
) => {
336 if let Some(ref qself
) = *maybe_qself
{
337 visitor
.visit_ty(&qself
.ty
);
339 visitor
.visit_path(path
, typ
.id
);
341 TyKind
::ObjectSum(ref ty
, ref bounds
) => {
342 visitor
.visit_ty(ty
);
343 walk_list
!(visitor
, visit_ty_param_bound
, bounds
);
345 TyKind
::Array(ref ty
, ref expression
) => {
346 visitor
.visit_ty(ty
);
347 visitor
.visit_expr(expression
)
349 TyKind
::PolyTraitRef(ref bounds
) => {
350 walk_list
!(visitor
, visit_ty_param_bound
, bounds
);
352 TyKind
::ImplTrait(ref bounds
) => {
353 walk_list
!(visitor
, visit_ty_param_bound
, bounds
);
355 TyKind
::Typeof(ref expression
) => {
356 visitor
.visit_expr(expression
)
358 TyKind
::Infer
| TyKind
::ImplicitSelf
=> {}
359 TyKind
::Mac(ref mac
) => {
360 visitor
.visit_mac(mac
)
365 pub fn walk_path
<V
: Visitor
>(visitor
: &mut V
, path
: &Path
) {
366 for segment
in &path
.segments
{
367 visitor
.visit_path_segment(path
.span
, segment
);
371 pub fn walk_path_list_item
<V
: Visitor
>(visitor
: &mut V
, _prefix
: &Path
, item
: &PathListItem
) {
372 visitor
.visit_ident(item
.span
, item
.node
.name
);
373 walk_opt_ident(visitor
, item
.span
, item
.node
.rename
);
376 pub fn walk_path_segment
<V
: Visitor
>(visitor
: &mut V
, path_span
: Span
, segment
: &PathSegment
) {
377 visitor
.visit_ident(path_span
, segment
.identifier
);
378 visitor
.visit_path_parameters(path_span
, &segment
.parameters
);
381 pub fn walk_path_parameters
<V
>(visitor
: &mut V
, _path_span
: Span
, path_parameters
: &PathParameters
)
384 match *path_parameters
{
385 PathParameters
::AngleBracketed(ref data
) => {
386 walk_list
!(visitor
, visit_ty
, &data
.types
);
387 walk_list
!(visitor
, visit_lifetime
, &data
.lifetimes
);
388 walk_list
!(visitor
, visit_assoc_type_binding
, &data
.bindings
);
390 PathParameters
::Parenthesized(ref data
) => {
391 walk_list
!(visitor
, visit_ty
, &data
.inputs
);
392 walk_list
!(visitor
, visit_ty
, &data
.output
);
397 pub fn walk_assoc_type_binding
<V
: Visitor
>(visitor
: &mut V
, type_binding
: &TypeBinding
) {
398 visitor
.visit_ident(type_binding
.span
, type_binding
.ident
);
399 visitor
.visit_ty(&type_binding
.ty
);
402 pub fn walk_pat
<V
: Visitor
>(visitor
: &mut V
, pattern
: &Pat
) {
404 PatKind
::TupleStruct(ref path
, ref children
, _
) => {
405 visitor
.visit_path(path
, pattern
.id
);
406 walk_list
!(visitor
, visit_pat
, children
);
408 PatKind
::Path(ref opt_qself
, ref path
) => {
409 if let Some(ref qself
) = *opt_qself
{
410 visitor
.visit_ty(&qself
.ty
);
412 visitor
.visit_path(path
, pattern
.id
)
414 PatKind
::Struct(ref path
, ref fields
, _
) => {
415 visitor
.visit_path(path
, pattern
.id
);
416 for field
in fields
{
417 visitor
.visit_ident(field
.span
, field
.node
.ident
);
418 visitor
.visit_pat(&field
.node
.pat
)
421 PatKind
::Tuple(ref tuple_elements
, _
) => {
422 walk_list
!(visitor
, visit_pat
, tuple_elements
);
424 PatKind
::Box(ref subpattern
) |
425 PatKind
::Ref(ref subpattern
, _
) => {
426 visitor
.visit_pat(subpattern
)
428 PatKind
::Ident(_
, ref pth1
, ref optional_subpattern
) => {
429 visitor
.visit_ident(pth1
.span
, pth1
.node
);
430 walk_list
!(visitor
, visit_pat
, optional_subpattern
);
432 PatKind
::Lit(ref expression
) => visitor
.visit_expr(expression
),
433 PatKind
::Range(ref lower_bound
, ref upper_bound
) => {
434 visitor
.visit_expr(lower_bound
);
435 visitor
.visit_expr(upper_bound
)
438 PatKind
::Slice(ref prepatterns
, ref slice_pattern
, ref postpatterns
) => {
439 walk_list
!(visitor
, visit_pat
, prepatterns
);
440 walk_list
!(visitor
, visit_pat
, slice_pattern
);
441 walk_list
!(visitor
, visit_pat
, postpatterns
);
443 PatKind
::Mac(ref mac
) => visitor
.visit_mac(mac
),
447 pub fn walk_foreign_item
<V
: Visitor
>(visitor
: &mut V
, foreign_item
: &ForeignItem
) {
448 visitor
.visit_vis(&foreign_item
.vis
);
449 visitor
.visit_ident(foreign_item
.span
, foreign_item
.ident
);
451 match foreign_item
.node
{
452 ForeignItemKind
::Fn(ref function_declaration
, ref generics
) => {
453 walk_fn_decl(visitor
, function_declaration
);
454 visitor
.visit_generics(generics
)
456 ForeignItemKind
::Static(ref typ
, _
) => visitor
.visit_ty(typ
),
459 walk_list
!(visitor
, visit_attribute
, &foreign_item
.attrs
);
462 pub fn walk_ty_param_bound
<V
: Visitor
>(visitor
: &mut V
, bound
: &TyParamBound
) {
464 TraitTyParamBound(ref typ
, ref modifier
) => {
465 visitor
.visit_poly_trait_ref(typ
, modifier
);
467 RegionTyParamBound(ref lifetime
) => {
468 visitor
.visit_lifetime(lifetime
);
473 pub fn walk_generics
<V
: Visitor
>(visitor
: &mut V
, generics
: &Generics
) {
474 for param
in &generics
.ty_params
{
475 visitor
.visit_ident(param
.span
, param
.ident
);
476 walk_list
!(visitor
, visit_ty_param_bound
, ¶m
.bounds
);
477 walk_list
!(visitor
, visit_ty
, ¶m
.default);
478 walk_list
!(visitor
, visit_attribute
, &*param
.attrs
);
480 walk_list
!(visitor
, visit_lifetime_def
, &generics
.lifetimes
);
481 for predicate
in &generics
.where_clause
.predicates
{
483 WherePredicate
::BoundPredicate(WhereBoundPredicate
{ref bounded_ty
,
487 visitor
.visit_ty(bounded_ty
);
488 walk_list
!(visitor
, visit_ty_param_bound
, bounds
);
489 walk_list
!(visitor
, visit_lifetime_def
, bound_lifetimes
);
491 WherePredicate
::RegionPredicate(WhereRegionPredicate
{ref lifetime
,
494 visitor
.visit_lifetime(lifetime
);
495 walk_list
!(visitor
, visit_lifetime
, bounds
);
497 WherePredicate
::EqPredicate(WhereEqPredicate
{id
,
501 visitor
.visit_path(path
, id
);
502 visitor
.visit_ty(ty
);
508 pub fn walk_fn_ret_ty
<V
: Visitor
>(visitor
: &mut V
, ret_ty
: &FunctionRetTy
) {
509 if let FunctionRetTy
::Ty(ref output_ty
) = *ret_ty
{
510 visitor
.visit_ty(output_ty
)
514 pub fn walk_fn_decl
<V
: Visitor
>(visitor
: &mut V
, function_declaration
: &FnDecl
) {
515 for argument
in &function_declaration
.inputs
{
516 visitor
.visit_pat(&argument
.pat
);
517 visitor
.visit_ty(&argument
.ty
)
519 visitor
.visit_fn_ret_ty(&function_declaration
.output
)
522 pub fn walk_fn_kind
<V
: Visitor
>(visitor
: &mut V
, function_kind
: FnKind
) {
523 match function_kind
{
524 FnKind
::ItemFn(_
, generics
, _
, _
, _
, _
) => {
525 visitor
.visit_generics(generics
);
527 FnKind
::Method(_
, ref sig
, _
) => {
528 visitor
.visit_generics(&sig
.generics
);
530 FnKind
::Closure
=> {}
534 pub fn walk_fn
<V
>(visitor
: &mut V
, kind
: FnKind
, declaration
: &FnDecl
, body
: &Block
, _span
: Span
)
537 walk_fn_kind(visitor
, kind
);
538 walk_fn_decl(visitor
, declaration
);
539 visitor
.visit_block(body
)
542 pub fn walk_trait_item
<V
: Visitor
>(visitor
: &mut V
, trait_item
: &TraitItem
) {
543 visitor
.visit_ident(trait_item
.span
, trait_item
.ident
);
544 walk_list
!(visitor
, visit_attribute
, &trait_item
.attrs
);
545 match trait_item
.node
{
546 TraitItemKind
::Const(ref ty
, ref default) => {
547 visitor
.visit_ty(ty
);
548 walk_list
!(visitor
, visit_expr
, default);
550 TraitItemKind
::Method(ref sig
, None
) => {
551 visitor
.visit_generics(&sig
.generics
);
552 walk_fn_decl(visitor
, &sig
.decl
);
554 TraitItemKind
::Method(ref sig
, Some(ref body
)) => {
555 visitor
.visit_fn(FnKind
::Method(trait_item
.ident
, sig
, None
), &sig
.decl
,
556 body
, trait_item
.span
, trait_item
.id
);
558 TraitItemKind
::Type(ref bounds
, ref default) => {
559 walk_list
!(visitor
, visit_ty_param_bound
, bounds
);
560 walk_list
!(visitor
, visit_ty
, default);
562 TraitItemKind
::Macro(ref mac
) => {
563 visitor
.visit_mac(mac
);
568 pub fn walk_impl_item
<V
: Visitor
>(visitor
: &mut V
, impl_item
: &ImplItem
) {
569 visitor
.visit_vis(&impl_item
.vis
);
570 visitor
.visit_ident(impl_item
.span
, impl_item
.ident
);
571 walk_list
!(visitor
, visit_attribute
, &impl_item
.attrs
);
572 match impl_item
.node
{
573 ImplItemKind
::Const(ref ty
, ref expr
) => {
574 visitor
.visit_ty(ty
);
575 visitor
.visit_expr(expr
);
577 ImplItemKind
::Method(ref sig
, ref body
) => {
578 visitor
.visit_fn(FnKind
::Method(impl_item
.ident
, sig
, Some(&impl_item
.vis
)), &sig
.decl
,
579 body
, impl_item
.span
, impl_item
.id
);
581 ImplItemKind
::Type(ref ty
) => {
582 visitor
.visit_ty(ty
);
584 ImplItemKind
::Macro(ref mac
) => {
585 visitor
.visit_mac(mac
);
590 pub fn walk_struct_def
<V
: Visitor
>(visitor
: &mut V
, struct_definition
: &VariantData
) {
591 walk_list
!(visitor
, visit_struct_field
, struct_definition
.fields());
594 pub fn walk_struct_field
<V
: Visitor
>(visitor
: &mut V
, struct_field
: &StructField
) {
595 visitor
.visit_vis(&struct_field
.vis
);
596 walk_opt_ident(visitor
, struct_field
.span
, struct_field
.ident
);
597 visitor
.visit_ty(&struct_field
.ty
);
598 walk_list
!(visitor
, visit_attribute
, &struct_field
.attrs
);
601 pub fn walk_block
<V
: Visitor
>(visitor
: &mut V
, block
: &Block
) {
602 walk_list
!(visitor
, visit_stmt
, &block
.stmts
);
605 pub fn walk_stmt
<V
: Visitor
>(visitor
: &mut V
, statement
: &Stmt
) {
606 match statement
.node
{
607 StmtKind
::Local(ref local
) => visitor
.visit_local(local
),
608 StmtKind
::Item(ref item
) => visitor
.visit_item(item
),
609 StmtKind
::Expr(ref expression
) | StmtKind
::Semi(ref expression
) => {
610 visitor
.visit_expr(expression
)
612 StmtKind
::Mac(ref mac
) => {
613 let (ref mac
, _
, ref attrs
) = **mac
;
614 visitor
.visit_mac(mac
);
615 for attr
in attrs
.iter() {
616 visitor
.visit_attribute(attr
);
622 pub fn walk_mac
<V
: Visitor
>(_
: &mut V
, _
: &Mac
) {
626 pub fn walk_expr
<V
: Visitor
>(visitor
: &mut V
, expression
: &Expr
) {
627 for attr
in expression
.attrs
.iter() {
628 visitor
.visit_attribute(attr
);
630 match expression
.node
{
631 ExprKind
::Box(ref subexpression
) => {
632 visitor
.visit_expr(subexpression
)
634 ExprKind
::InPlace(ref place
, ref subexpression
) => {
635 visitor
.visit_expr(place
);
636 visitor
.visit_expr(subexpression
)
638 ExprKind
::Vec(ref subexpressions
) => {
639 walk_list
!(visitor
, visit_expr
, subexpressions
);
641 ExprKind
::Repeat(ref element
, ref count
) => {
642 visitor
.visit_expr(element
);
643 visitor
.visit_expr(count
)
645 ExprKind
::Struct(ref path
, ref fields
, ref optional_base
) => {
646 visitor
.visit_path(path
, expression
.id
);
647 for field
in fields
{
648 visitor
.visit_ident(field
.ident
.span
, field
.ident
.node
);
649 visitor
.visit_expr(&field
.expr
)
651 walk_list
!(visitor
, visit_expr
, optional_base
);
653 ExprKind
::Tup(ref subexpressions
) => {
654 walk_list
!(visitor
, visit_expr
, subexpressions
);
656 ExprKind
::Call(ref callee_expression
, ref arguments
) => {
657 visitor
.visit_expr(callee_expression
);
658 walk_list
!(visitor
, visit_expr
, arguments
);
660 ExprKind
::MethodCall(ref ident
, ref types
, ref arguments
) => {
661 visitor
.visit_ident(ident
.span
, ident
.node
);
662 walk_list
!(visitor
, visit_ty
, types
);
663 walk_list
!(visitor
, visit_expr
, arguments
);
665 ExprKind
::Binary(_
, ref left_expression
, ref right_expression
) => {
666 visitor
.visit_expr(left_expression
);
667 visitor
.visit_expr(right_expression
)
669 ExprKind
::AddrOf(_
, ref subexpression
) | ExprKind
::Unary(_
, ref subexpression
) => {
670 visitor
.visit_expr(subexpression
)
672 ExprKind
::Lit(_
) => {}
673 ExprKind
::Cast(ref subexpression
, ref typ
) | ExprKind
::Type(ref subexpression
, ref typ
) => {
674 visitor
.visit_expr(subexpression
);
675 visitor
.visit_ty(typ
)
677 ExprKind
::If(ref head_expression
, ref if_block
, ref optional_else
) => {
678 visitor
.visit_expr(head_expression
);
679 visitor
.visit_block(if_block
);
680 walk_list
!(visitor
, visit_expr
, optional_else
);
682 ExprKind
::While(ref subexpression
, ref block
, ref opt_sp_ident
) => {
683 visitor
.visit_expr(subexpression
);
684 visitor
.visit_block(block
);
685 walk_opt_sp_ident(visitor
, opt_sp_ident
);
687 ExprKind
::IfLet(ref pattern
, ref subexpression
, ref if_block
, ref optional_else
) => {
688 visitor
.visit_pat(pattern
);
689 visitor
.visit_expr(subexpression
);
690 visitor
.visit_block(if_block
);
691 walk_list
!(visitor
, visit_expr
, optional_else
);
693 ExprKind
::WhileLet(ref pattern
, ref subexpression
, ref block
, ref opt_sp_ident
) => {
694 visitor
.visit_pat(pattern
);
695 visitor
.visit_expr(subexpression
);
696 visitor
.visit_block(block
);
697 walk_opt_sp_ident(visitor
, opt_sp_ident
);
699 ExprKind
::ForLoop(ref pattern
, ref subexpression
, ref block
, ref opt_sp_ident
) => {
700 visitor
.visit_pat(pattern
);
701 visitor
.visit_expr(subexpression
);
702 visitor
.visit_block(block
);
703 walk_opt_sp_ident(visitor
, opt_sp_ident
);
705 ExprKind
::Loop(ref block
, ref opt_sp_ident
) => {
706 visitor
.visit_block(block
);
707 walk_opt_sp_ident(visitor
, opt_sp_ident
);
709 ExprKind
::Match(ref subexpression
, ref arms
) => {
710 visitor
.visit_expr(subexpression
);
711 walk_list
!(visitor
, visit_arm
, arms
);
713 ExprKind
::Closure(_
, ref function_declaration
, ref body
, _decl_span
) => {
714 visitor
.visit_fn(FnKind
::Closure
,
715 function_declaration
,
720 ExprKind
::Block(ref block
) => visitor
.visit_block(block
),
721 ExprKind
::Assign(ref left_hand_expression
, ref right_hand_expression
) => {
722 visitor
.visit_expr(left_hand_expression
);
723 visitor
.visit_expr(right_hand_expression
);
725 ExprKind
::AssignOp(_
, ref left_expression
, ref right_expression
) => {
726 visitor
.visit_expr(left_expression
);
727 visitor
.visit_expr(right_expression
);
729 ExprKind
::Field(ref subexpression
, ref ident
) => {
730 visitor
.visit_expr(subexpression
);
731 visitor
.visit_ident(ident
.span
, ident
.node
);
733 ExprKind
::TupField(ref subexpression
, _
) => {
734 visitor
.visit_expr(subexpression
);
736 ExprKind
::Index(ref main_expression
, ref index_expression
) => {
737 visitor
.visit_expr(main_expression
);
738 visitor
.visit_expr(index_expression
)
740 ExprKind
::Range(ref start
, ref end
, _
) => {
741 walk_list
!(visitor
, visit_expr
, start
);
742 walk_list
!(visitor
, visit_expr
, end
);
744 ExprKind
::Path(ref maybe_qself
, ref path
) => {
745 if let Some(ref qself
) = *maybe_qself
{
746 visitor
.visit_ty(&qself
.ty
);
748 visitor
.visit_path(path
, expression
.id
)
750 ExprKind
::Break(ref opt_sp_ident
) | ExprKind
::Continue(ref opt_sp_ident
) => {
751 walk_opt_sp_ident(visitor
, opt_sp_ident
);
753 ExprKind
::Ret(ref optional_expression
) => {
754 walk_list
!(visitor
, visit_expr
, optional_expression
);
756 ExprKind
::Mac(ref mac
) => visitor
.visit_mac(mac
),
757 ExprKind
::Paren(ref subexpression
) => {
758 visitor
.visit_expr(subexpression
)
760 ExprKind
::InlineAsm(ref ia
) => {
761 for &(_
, ref input
) in &ia
.inputs
{
762 visitor
.visit_expr(&input
)
764 for output
in &ia
.outputs
{
765 visitor
.visit_expr(&output
.expr
)
768 ExprKind
::Try(ref subexpression
) => {
769 visitor
.visit_expr(subexpression
)
773 visitor
.visit_expr_post(expression
)
776 pub fn walk_arm
<V
: Visitor
>(visitor
: &mut V
, arm
: &Arm
) {
777 walk_list
!(visitor
, visit_pat
, &arm
.pats
);
778 walk_list
!(visitor
, visit_expr
, &arm
.guard
);
779 visitor
.visit_expr(&arm
.body
);
780 walk_list
!(visitor
, visit_attribute
, &arm
.attrs
);
783 pub fn walk_vis
<V
: Visitor
>(visitor
: &mut V
, vis
: &Visibility
) {
784 if let Visibility
::Restricted { ref path, id }
= *vis
{
785 visitor
.visit_path(path
, id
);