]> git.proxmox.com Git - rustc.git/blame - src/libsyntax/visit.rs
Imported Upstream version 1.9.0+dfsg1
[rustc.git] / src / libsyntax / visit.rs
CommitLineData
b039eaaf 1// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
223e47cc
LB
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
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.
10
1a4d82fc
JJ
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.
15//!
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.
21//!
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.
25
1a4d82fc 26use abi::Abi;
223e47cc 27use ast::*;
92a42be0 28use attr::ThinAttributesExt;
1a4d82fc 29use codemap::Span;
1a4d82fc 30
e9174d1e 31#[derive(Copy, Clone, PartialEq, Eq)]
1a4d82fc
JJ
32pub enum FnKind<'a> {
33 /// fn foo() or extern "Abi" fn foo()
54a0048b 34 ItemFn(Ident, &'a Generics, Unsafety, Constness, Abi, &'a Visibility),
1a4d82fc
JJ
35
36 /// fn foo(&self)
54a0048b 37 Method(Ident, &'a MethodSig, Option<&'a Visibility>),
1a4d82fc 38
e9174d1e
SL
39 /// |x, y| {}
40 Closure,
1a4d82fc
JJ
41}
42
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`.
47///
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.)
52pub trait Visitor<'v> : Sized {
53 fn visit_name(&mut self, _span: Span, _name: Name) {
54 // Nothing to do.
55 }
56 fn visit_ident(&mut self, span: Span, ident: Ident) {
b039eaaf 57 walk_ident(self, span, ident);
1a4d82fc
JJ
58 }
59 fn visit_mod(&mut self, m: &'v Mod, _s: Span, _n: NodeId) { walk_mod(self, m) }
1a4d82fc
JJ
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)
74 }
c34b1796
AL
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) }
1a4d82fc
JJ
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)
80 }
81 fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef, m: &'v TraitBoundModifier) {
82 walk_poly_trait_ref(self, t, m)
83 }
b039eaaf
SL
84 fn visit_variant_data(&mut self, s: &'v VariantData, _: Ident,
85 _: &'v Generics, _: NodeId, _: Span) {
1a4d82fc
JJ
86 walk_struct_def(self, s)
87 }
88 fn visit_struct_field(&mut self, s: &'v StructField) { walk_struct_field(self, s) }
c1a9b12d 89 fn visit_enum_def(&mut self, enum_definition: &'v EnumDef,
b039eaaf
SL
90 generics: &'v Generics, item_id: NodeId, _: Span) {
91 walk_enum_def(self, enum_definition, generics, item_id)
c1a9b12d 92 }
b039eaaf
SL
93 fn visit_variant(&mut self, v: &'v Variant, g: &'v Generics, item_id: NodeId) {
94 walk_variant(self, v, g, item_id)
1a4d82fc 95 }
b039eaaf
SL
96 fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
97 walk_lifetime(self, lifetime)
1a4d82fc
JJ
98 }
99 fn visit_lifetime_def(&mut self, lifetime: &'v LifetimeDef) {
100 walk_lifetime_def(self, lifetime)
101 }
102 fn visit_explicit_self(&mut self, es: &'v ExplicitSelf) {
103 walk_explicit_self(self, es)
104 }
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)
112 }
b039eaaf 113 fn visit_path(&mut self, path: &'v Path, _id: NodeId) {
1a4d82fc
JJ
114 walk_path(self, path)
115 }
b039eaaf
SL
116 fn visit_path_list_item(&mut self, prefix: &'v Path, item: &'v PathListItem) {
117 walk_path_list_item(self, prefix, item)
118 }
1a4d82fc
JJ
119 fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment) {
120 walk_path_segment(self, path_span, path_segment)
121 }
122 fn visit_path_parameters(&mut self, path_span: Span, path_parameters: &'v PathParameters) {
123 walk_path_parameters(self, path_span, path_parameters)
124 }
125 fn visit_assoc_type_binding(&mut self, type_binding: &'v TypeBinding) {
126 walk_assoc_type_binding(self, type_binding)
127 }
128 fn visit_attribute(&mut self, _attr: &'v Attribute) {}
b039eaaf
SL
129 fn visit_macro_def(&mut self, macro_def: &'v MacroDef) {
130 walk_macro_def(self, macro_def)
131 }
54a0048b
SL
132 fn visit_vis(&mut self, vis: &'v Visibility) {
133 walk_vis(self, vis)
134 }
223e47cc
LB
135}
136
b039eaaf
SL
137#[macro_export]
138macro_rules! walk_list {
139 ($visitor: expr, $method: ident, $list: expr) => {
140 for elem in $list {
141 $visitor.$method(elem)
142 }
143 };
144 ($visitor: expr, $method: ident, $list: expr, $($extra_args: expr),*) => {
145 for elem in $list {
146 $visitor.$method(elem, $($extra_args,)*)
147 }
1a4d82fc
JJ
148 }
149}
150
b039eaaf
SL
151pub fn walk_opt_name<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, opt_name: Option<Name>) {
152 for name in opt_name {
153 visitor.visit_name(span, name);
1a4d82fc
JJ
154 }
155}
156
b039eaaf
SL
157pub fn walk_opt_ident<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, opt_ident: Option<Ident>) {
158 for ident in opt_ident {
159 visitor.visit_ident(span, ident);
160 }
1a4d82fc
JJ
161}
162
b039eaaf
SL
163pub fn walk_ident<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, ident: Ident) {
164 visitor.visit_name(span, ident.name);
165}
166
167pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate) {
168 visitor.visit_mod(&krate.module, krate.span, CRATE_NODE_ID);
169 walk_list!(visitor, visit_attribute, &krate.attrs);
170 walk_list!(visitor, visit_macro_def, &krate.exported_macros);
171}
172
173pub fn walk_macro_def<'v, V: Visitor<'v>>(visitor: &mut V, macro_def: &'v MacroDef) {
174 visitor.visit_ident(macro_def.span, macro_def.ident);
175 walk_opt_ident(visitor, macro_def.span, macro_def.imported_from);
176 walk_list!(visitor, visit_attribute, &macro_def.attrs);
1a4d82fc
JJ
177}
178
b039eaaf
SL
179pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod) {
180 walk_list!(visitor, visit_item, &module.items);
1a4d82fc
JJ
181}
182
b039eaaf
SL
183pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) {
184 visitor.visit_pat(&local.pat);
185 walk_list!(visitor, visit_ty, &local.ty);
186 walk_list!(visitor, visit_expr, &local.init);
187}
188
189pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) {
190 visitor.visit_name(lifetime.span, lifetime.name);
191}
192
193pub fn walk_lifetime_def<'v, V: Visitor<'v>>(visitor: &mut V,
194 lifetime_def: &'v LifetimeDef) {
195 visitor.visit_lifetime(&lifetime_def.lifetime);
196 walk_list!(visitor, visit_lifetime, &lifetime_def.bounds);
1a4d82fc
JJ
197}
198
199pub fn walk_explicit_self<'v, V: Visitor<'v>>(visitor: &mut V,
200 explicit_self: &'v ExplicitSelf) {
201 match explicit_self.node {
7453a54e
SL
202 SelfKind::Static => {},
203 SelfKind::Value(ident) => {
b039eaaf
SL
204 visitor.visit_ident(explicit_self.span, ident)
205 }
7453a54e 206 SelfKind::Region(ref opt_lifetime, _, ident) => {
b039eaaf
SL
207 visitor.visit_ident(explicit_self.span, ident);
208 walk_list!(visitor, visit_lifetime, opt_lifetime);
209 }
7453a54e 210 SelfKind::Explicit(ref typ, ident) => {
b039eaaf
SL
211 visitor.visit_ident(explicit_self.span, ident);
212 visitor.visit_ty(typ)
1a4d82fc 213 }
1a4d82fc
JJ
214 }
215}
216
1a4d82fc
JJ
217pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V,
218 trait_ref: &'v PolyTraitRef,
219 _modifier: &'v TraitBoundModifier)
220 where V: Visitor<'v>
221{
b039eaaf 222 walk_list!(visitor, visit_lifetime_def, &trait_ref.bound_lifetimes);
1a4d82fc
JJ
223 visitor.visit_trait_ref(&trait_ref.trait_ref);
224}
225
1a4d82fc
JJ
226pub fn walk_trait_ref<'v,V>(visitor: &mut V,
227 trait_ref: &'v TraitRef)
228 where V: Visitor<'v>
229{
230 visitor.visit_path(&trait_ref.path, trait_ref.ref_id)
231}
232
233pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
234 visitor.visit_ident(item.span, item.ident);
235 match item.node {
7453a54e 236 ItemKind::ExternCrate(opt_name) => {
b039eaaf
SL
237 walk_opt_name(visitor, item.span, opt_name)
238 }
7453a54e 239 ItemKind::Use(ref vp) => {
85aaf69f
SL
240 match vp.node {
241 ViewPathSimple(ident, ref path) => {
242 visitor.visit_ident(vp.span, ident);
243 visitor.visit_path(path, item.id);
244 }
245 ViewPathGlob(ref path) => {
246 visitor.visit_path(path, item.id);
247 }
248 ViewPathList(ref prefix, ref list) => {
b039eaaf
SL
249 if !list.is_empty() {
250 for item in list {
251 visitor.visit_path_list_item(prefix, item)
85aaf69f 252 }
b039eaaf
SL
253 } else {
254 visitor.visit_path(prefix, item.id);
85aaf69f 255 }
85aaf69f
SL
256 }
257 }
258 }
7453a54e
SL
259 ItemKind::Static(ref typ, _, ref expr) |
260 ItemKind::Const(ref typ, ref expr) => {
b039eaaf
SL
261 visitor.visit_ty(typ);
262 visitor.visit_expr(expr);
1a4d82fc 263 }
7453a54e 264 ItemKind::Fn(ref declaration, unsafety, constness, abi, ref generics, ref body) => {
e9174d1e 265 visitor.visit_fn(FnKind::ItemFn(item.ident, generics, unsafety,
54a0048b 266 constness, abi, &item.vis),
b039eaaf
SL
267 declaration,
268 body,
1a4d82fc
JJ
269 item.span,
270 item.id)
271 }
7453a54e 272 ItemKind::Mod(ref module) => {
1a4d82fc
JJ
273 visitor.visit_mod(module, item.span, item.id)
274 }
7453a54e 275 ItemKind::ForeignMod(ref foreign_module) => {
b039eaaf 276 walk_list!(visitor, visit_foreign_item, &foreign_module.items);
223e47cc 277 }
7453a54e 278 ItemKind::Ty(ref typ, ref type_parameters) => {
b039eaaf 279 visitor.visit_ty(typ);
1a4d82fc
JJ
280 visitor.visit_generics(type_parameters)
281 }
7453a54e 282 ItemKind::Enum(ref enum_definition, ref type_parameters) => {
1a4d82fc 283 visitor.visit_generics(type_parameters);
b039eaaf 284 visitor.visit_enum_def(enum_definition, type_parameters, item.id, item.span)
1a4d82fc 285 }
7453a54e 286 ItemKind::DefaultImpl(_, ref trait_ref) => {
c34b1796
AL
287 visitor.visit_trait_ref(trait_ref)
288 }
7453a54e 289 ItemKind::Impl(_, _,
1a4d82fc 290 ref type_parameters,
b039eaaf 291 ref opt_trait_reference,
1a4d82fc
JJ
292 ref typ,
293 ref impl_items) => {
294 visitor.visit_generics(type_parameters);
b039eaaf
SL
295 walk_list!(visitor, visit_trait_ref, opt_trait_reference);
296 visitor.visit_ty(typ);
297 walk_list!(visitor, visit_impl_item, impl_items);
970d7e83 298 }
7453a54e 299 ItemKind::Struct(ref struct_definition, ref generics) => {
1a4d82fc 300 visitor.visit_generics(generics);
b039eaaf
SL
301 visitor.visit_variant_data(struct_definition, item.ident,
302 generics, item.id, item.span);
1a4d82fc 303 }
7453a54e 304 ItemKind::Trait(_, ref generics, ref bounds, ref methods) => {
1a4d82fc 305 visitor.visit_generics(generics);
b039eaaf
SL
306 walk_list!(visitor, visit_ty_param_bound, bounds);
307 walk_list!(visitor, visit_trait_item, methods);
1a4d82fc 308 }
7453a54e 309 ItemKind::Mac(ref mac) => visitor.visit_mac(mac),
1a4d82fc 310 }
b039eaaf 311 walk_list!(visitor, visit_attribute, &item.attrs);
223e47cc
LB
312}
313
1a4d82fc
JJ
314pub fn walk_enum_def<'v, V: Visitor<'v>>(visitor: &mut V,
315 enum_definition: &'v EnumDef,
b039eaaf
SL
316 generics: &'v Generics,
317 item_id: NodeId) {
318 walk_list!(visitor, visit_variant, &enum_definition.variants, generics, item_id);
1a4d82fc 319}
223e47cc 320
1a4d82fc
JJ
321pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V,
322 variant: &'v Variant,
b039eaaf
SL
323 generics: &'v Generics,
324 item_id: NodeId) {
1a4d82fc 325 visitor.visit_ident(variant.span, variant.node.name);
b039eaaf
SL
326 visitor.visit_variant_data(&variant.node.data, variant.node.name,
327 generics, item_id, variant.span);
328 walk_list!(visitor, visit_expr, &variant.node.disr_expr);
329 walk_list!(visitor, visit_attribute, &variant.node.attrs);
1a4d82fc
JJ
330}
331
332pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
333 match typ.node {
7453a54e 334 TyKind::Vec(ref ty) | TyKind::Paren(ref ty) => {
b039eaaf 335 visitor.visit_ty(ty)
1a4d82fc 336 }
7453a54e 337 TyKind::Ptr(ref mutable_type) => {
b039eaaf 338 visitor.visit_ty(&mutable_type.ty)
1a4d82fc 339 }
7453a54e 340 TyKind::Rptr(ref opt_lifetime, ref mutable_type) => {
b039eaaf
SL
341 walk_list!(visitor, visit_lifetime, opt_lifetime);
342 visitor.visit_ty(&mutable_type.ty)
1a4d82fc 343 }
7453a54e 344 TyKind::Tup(ref tuple_element_types) => {
b039eaaf 345 walk_list!(visitor, visit_ty, tuple_element_types);
1a4d82fc 346 }
7453a54e 347 TyKind::BareFn(ref function_declaration) => {
b039eaaf
SL
348 walk_fn_decl(visitor, &function_declaration.decl);
349 walk_list!(visitor, visit_lifetime_def, &function_declaration.lifetimes);
1a4d82fc 350 }
7453a54e 351 TyKind::Path(ref maybe_qself, ref path) => {
c34b1796
AL
352 if let Some(ref qself) = *maybe_qself {
353 visitor.visit_ty(&qself.ty);
354 }
355 visitor.visit_path(path, typ.id);
1a4d82fc 356 }
7453a54e 357 TyKind::ObjectSum(ref ty, ref bounds) => {
b039eaaf
SL
358 visitor.visit_ty(ty);
359 walk_list!(visitor, visit_ty_param_bound, bounds);
1a4d82fc 360 }
7453a54e 361 TyKind::FixedLengthVec(ref ty, ref expression) => {
b039eaaf
SL
362 visitor.visit_ty(ty);
363 visitor.visit_expr(expression)
1a4d82fc 364 }
7453a54e 365 TyKind::PolyTraitRef(ref bounds) => {
b039eaaf 366 walk_list!(visitor, visit_ty_param_bound, bounds);
1a4d82fc 367 }
7453a54e 368 TyKind::Typeof(ref expression) => {
b039eaaf 369 visitor.visit_expr(expression)
1a4d82fc 370 }
7453a54e
SL
371 TyKind::Infer => {}
372 TyKind::Mac(ref mac) => {
e9174d1e
SL
373 visitor.visit_mac(mac)
374 }
1a4d82fc
JJ
375 }
376}
377
1a4d82fc 378pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) {
85aaf69f 379 for segment in &path.segments {
1a4d82fc
JJ
380 visitor.visit_path_segment(path.span, segment);
381 }
382}
383
b039eaaf
SL
384pub fn walk_path_list_item<'v, V: Visitor<'v>>(visitor: &mut V, prefix: &'v Path,
385 item: &'v PathListItem) {
386 for segment in &prefix.segments {
387 visitor.visit_path_segment(prefix.span, segment);
388 }
389
390 walk_opt_ident(visitor, item.span, item.node.name());
391 walk_opt_ident(visitor, item.span, item.node.rename());
392}
393
1a4d82fc
JJ
394pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V,
395 path_span: Span,
396 segment: &'v PathSegment) {
397 visitor.visit_ident(path_span, segment.identifier);
398 visitor.visit_path_parameters(path_span, &segment.parameters);
399}
400
401pub fn walk_path_parameters<'v, V: Visitor<'v>>(visitor: &mut V,
402 _path_span: Span,
403 path_parameters: &'v PathParameters) {
404 match *path_parameters {
9cc50fc6 405 PathParameters::AngleBracketed(ref data) => {
b039eaaf
SL
406 walk_list!(visitor, visit_ty, &data.types);
407 walk_list!(visitor, visit_lifetime, &data.lifetimes);
408 walk_list!(visitor, visit_assoc_type_binding, &data.bindings);
1a4d82fc 409 }
9cc50fc6 410 PathParameters::Parenthesized(ref data) => {
b039eaaf
SL
411 walk_list!(visitor, visit_ty, &data.inputs);
412 walk_list!(visitor, visit_ty, &data.output);
1a4d82fc
JJ
413 }
414 }
415}
416
417pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(visitor: &mut V,
418 type_binding: &'v TypeBinding) {
419 visitor.visit_ident(type_binding.span, type_binding.ident);
b039eaaf 420 visitor.visit_ty(&type_binding.ty);
1a4d82fc
JJ
421}
422
423pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
424 match pattern.node {
7453a54e 425 PatKind::TupleStruct(ref path, ref opt_children) => {
1a4d82fc 426 visitor.visit_path(path, pattern.id);
b039eaaf
SL
427 if let Some(ref children) = *opt_children {
428 walk_list!(visitor, visit_pat, children);
223e47cc
LB
429 }
430 }
7453a54e
SL
431 PatKind::Path(ref path) => {
432 visitor.visit_path(path, pattern.id);
433 }
434 PatKind::QPath(ref qself, ref path) => {
d9579d0f
AL
435 visitor.visit_ty(&qself.ty);
436 visitor.visit_path(path, pattern.id)
437 }
7453a54e 438 PatKind::Struct(ref path, ref fields, _) => {
1a4d82fc 439 visitor.visit_path(path, pattern.id);
85aaf69f 440 for field in fields {
b039eaaf
SL
441 visitor.visit_ident(field.span, field.node.ident);
442 visitor.visit_pat(&field.node.pat)
223e47cc
LB
443 }
444 }
7453a54e 445 PatKind::Tup(ref tuple_elements) => {
b039eaaf 446 walk_list!(visitor, visit_pat, tuple_elements);
1a4d82fc 447 }
7453a54e
SL
448 PatKind::Box(ref subpattern) |
449 PatKind::Ref(ref subpattern, _) => {
b039eaaf 450 visitor.visit_pat(subpattern)
1a4d82fc 451 }
7453a54e 452 PatKind::Ident(_, ref pth1, ref optional_subpattern) => {
1a4d82fc 453 visitor.visit_ident(pth1.span, pth1.node);
b039eaaf 454 walk_list!(visitor, visit_pat, optional_subpattern);
223e47cc 455 }
7453a54e
SL
456 PatKind::Lit(ref expression) => visitor.visit_expr(expression),
457 PatKind::Range(ref lower_bound, ref upper_bound) => {
b039eaaf
SL
458 visitor.visit_expr(lower_bound);
459 visitor.visit_expr(upper_bound)
223e47cc 460 }
7453a54e
SL
461 PatKind::Wild => (),
462 PatKind::Vec(ref prepatterns, ref slice_pattern, ref postpatterns) => {
b039eaaf
SL
463 walk_list!(visitor, visit_pat, prepatterns);
464 walk_list!(visitor, visit_pat, slice_pattern);
465 walk_list!(visitor, visit_pat, postpatterns);
223e47cc 466 }
7453a54e 467 PatKind::Mac(ref mac) => visitor.visit_mac(mac),
1a4d82fc
JJ
468 }
469}
470
471pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V,
472 foreign_item: &'v ForeignItem) {
473 visitor.visit_ident(foreign_item.span, foreign_item.ident);
474
475 match foreign_item.node {
7453a54e 476 ForeignItemKind::Fn(ref function_declaration, ref generics) => {
b039eaaf 477 walk_fn_decl(visitor, function_declaration);
1a4d82fc
JJ
478 visitor.visit_generics(generics)
479 }
7453a54e 480 ForeignItemKind::Static(ref typ, _) => visitor.visit_ty(typ),
223e47cc 481 }
223e47cc 482
b039eaaf 483 walk_list!(visitor, visit_attribute, &foreign_item.attrs);
1a4d82fc
JJ
484}
485
486pub fn walk_ty_param_bound<'v, V: Visitor<'v>>(visitor: &mut V,
487 bound: &'v TyParamBound) {
488 match *bound {
489 TraitTyParamBound(ref typ, ref modifier) => {
490 visitor.visit_poly_trait_ref(typ, modifier);
223e47cc 491 }
1a4d82fc 492 RegionTyParamBound(ref lifetime) => {
b039eaaf 493 visitor.visit_lifetime(lifetime);
223e47cc
LB
494 }
495 }
496}
497
1a4d82fc 498pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics) {
b039eaaf 499 for param in &generics.ty_params {
c34b1796 500 visitor.visit_ident(param.span, param.ident);
b039eaaf
SL
501 walk_list!(visitor, visit_ty_param_bound, &param.bounds);
502 walk_list!(visitor, visit_ty, &param.default);
1a4d82fc 503 }
b039eaaf 504 walk_list!(visitor, visit_lifetime_def, &generics.lifetimes);
85aaf69f 505 for predicate in &generics.where_clause.predicates {
92a42be0
SL
506 match *predicate {
507 WherePredicate::BoundPredicate(WhereBoundPredicate{ref bounded_ty,
508 ref bounds,
509 ref bound_lifetimes,
510 ..}) => {
b039eaaf
SL
511 visitor.visit_ty(bounded_ty);
512 walk_list!(visitor, visit_ty_param_bound, bounds);
513 walk_list!(visitor, visit_lifetime_def, bound_lifetimes);
1a4d82fc 514 }
92a42be0
SL
515 WherePredicate::RegionPredicate(WhereRegionPredicate{ref lifetime,
516 ref bounds,
517 ..}) => {
b039eaaf
SL
518 visitor.visit_lifetime(lifetime);
519 walk_list!(visitor, visit_lifetime, bounds);
1a4d82fc 520 }
92a42be0
SL
521 WherePredicate::EqPredicate(WhereEqPredicate{id,
522 ref path,
523 ref ty,
524 ..}) => {
1a4d82fc 525 visitor.visit_path(path, id);
b039eaaf 526 visitor.visit_ty(ty);
1a4d82fc 527 }
223e47cc
LB
528 }
529 }
530}
531
1a4d82fc 532pub fn walk_fn_ret_ty<'v, V: Visitor<'v>>(visitor: &mut V, ret_ty: &'v FunctionRetTy) {
7453a54e 533 if let FunctionRetTy::Ty(ref output_ty) = *ret_ty {
b039eaaf 534 visitor.visit_ty(output_ty)
223e47cc
LB
535 }
536}
537
1a4d82fc 538pub fn walk_fn_decl<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: &'v FnDecl) {
85aaf69f 539 for argument in &function_declaration.inputs {
b039eaaf
SL
540 visitor.visit_pat(&argument.pat);
541 visitor.visit_ty(&argument.ty)
223e47cc 542 }
1a4d82fc 543 walk_fn_ret_ty(visitor, &function_declaration.output)
223e47cc
LB
544}
545
b039eaaf
SL
546pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V,
547 function_kind: FnKind<'v>) {
1a4d82fc 548 match function_kind {
e9174d1e 549 FnKind::ItemFn(_, generics, _, _, _, _) => {
1a4d82fc
JJ
550 visitor.visit_generics(generics);
551 }
54a0048b 552 FnKind::Method(_, ref sig, _) => {
c34b1796
AL
553 visitor.visit_generics(&sig.generics);
554 visitor.visit_explicit_self(&sig.explicit_self);
1a4d82fc 555 }
b039eaaf 556 FnKind::Closure => {}
1a4d82fc 557 }
b039eaaf 558}
1a4d82fc 559
b039eaaf
SL
560pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V,
561 function_kind: FnKind<'v>,
562 function_declaration: &'v FnDecl,
563 function_body: &'v Block,
564 _span: Span) {
565 walk_fn_decl(visitor, function_declaration);
566 walk_fn_kind(visitor, function_kind);
1a4d82fc 567 visitor.visit_block(function_body)
223e47cc
LB
568}
569
c34b1796
AL
570pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem) {
571 visitor.visit_ident(trait_item.span, trait_item.ident);
b039eaaf 572 walk_list!(visitor, visit_attribute, &trait_item.attrs);
c34b1796 573 match trait_item.node {
7453a54e 574 TraitItemKind::Const(ref ty, ref default) => {
d9579d0f 575 visitor.visit_ty(ty);
b039eaaf 576 walk_list!(visitor, visit_expr, default);
d9579d0f 577 }
7453a54e 578 TraitItemKind::Method(ref sig, None) => {
c34b1796
AL
579 visitor.visit_explicit_self(&sig.explicit_self);
580 visitor.visit_generics(&sig.generics);
581 walk_fn_decl(visitor, &sig.decl);
582 }
7453a54e 583 TraitItemKind::Method(ref sig, Some(ref body)) => {
e9174d1e 584 visitor.visit_fn(FnKind::Method(trait_item.ident, sig, None), &sig.decl,
c34b1796
AL
585 body, trait_item.span, trait_item.id);
586 }
7453a54e 587 TraitItemKind::Type(ref bounds, ref default) => {
b039eaaf
SL
588 walk_list!(visitor, visit_ty_param_bound, bounds);
589 walk_list!(visitor, visit_ty, default);
c34b1796
AL
590 }
591 }
223e47cc
LB
592}
593
c34b1796
AL
594pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem) {
595 visitor.visit_ident(impl_item.span, impl_item.ident);
b039eaaf 596 walk_list!(visitor, visit_attribute, &impl_item.attrs);
c34b1796 597 match impl_item.node {
92a42be0 598 ImplItemKind::Const(ref ty, ref expr) => {
d9579d0f
AL
599 visitor.visit_ty(ty);
600 visitor.visit_expr(expr);
601 }
92a42be0 602 ImplItemKind::Method(ref sig, ref body) => {
54a0048b 603 visitor.visit_fn(FnKind::Method(impl_item.ident, sig, Some(&impl_item.vis)), &sig.decl,
c34b1796
AL
604 body, impl_item.span, impl_item.id);
605 }
92a42be0 606 ImplItemKind::Type(ref ty) => {
c34b1796
AL
607 visitor.visit_ty(ty);
608 }
92a42be0 609 ImplItemKind::Macro(ref mac) => {
c34b1796 610 visitor.visit_mac(mac);
1a4d82fc 611 }
223e47cc
LB
612 }
613}
614
1a4d82fc 615pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V,
b039eaaf
SL
616 struct_definition: &'v VariantData) {
617 walk_list!(visitor, visit_struct_field, struct_definition.fields());
223e47cc
LB
618}
619
1a4d82fc
JJ
620pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V,
621 struct_field: &'v StructField) {
54a0048b
SL
622 walk_opt_ident(visitor, struct_field.span, struct_field.ident);
623 visitor.visit_ty(&struct_field.ty);
624 walk_list!(visitor, visit_attribute, &struct_field.attrs);
223e47cc
LB
625}
626
1a4d82fc 627pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block) {
b039eaaf
SL
628 walk_list!(visitor, visit_stmt, &block.stmts);
629 walk_list!(visitor, visit_expr, &block.expr);
223e47cc
LB
630}
631
1a4d82fc
JJ
632pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) {
633 match statement.node {
7453a54e
SL
634 StmtKind::Decl(ref declaration, _) => visitor.visit_decl(declaration),
635 StmtKind::Expr(ref expression, _) | StmtKind::Semi(ref expression, _) => {
b039eaaf 636 visitor.visit_expr(expression)
1a4d82fc 637 }
7453a54e 638 StmtKind::Mac(ref mac, _, ref attrs) => {
92a42be0
SL
639 visitor.visit_mac(mac);
640 for attr in attrs.as_attr_slice() {
641 visitor.visit_attribute(attr);
642 }
643 }
223e47cc
LB
644 }
645}
646
1a4d82fc
JJ
647pub fn walk_decl<'v, V: Visitor<'v>>(visitor: &mut V, declaration: &'v Decl) {
648 match declaration.node {
7453a54e
SL
649 DeclKind::Local(ref local) => visitor.visit_local(local),
650 DeclKind::Item(ref item) => visitor.visit_item(item),
1a4d82fc 651 }
223e47cc
LB
652}
653
1a4d82fc
JJ
654pub fn walk_mac<'v, V: Visitor<'v>>(_: &mut V, _: &'v Mac) {
655 // Empty!
223e47cc
LB
656}
657
1a4d82fc
JJ
658pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
659 match expression.node {
7453a54e 660 ExprKind::Box(ref subexpression) => {
b039eaaf
SL
661 visitor.visit_expr(subexpression)
662 }
7453a54e 663 ExprKind::InPlace(ref place, ref subexpression) => {
b039eaaf
SL
664 visitor.visit_expr(place);
665 visitor.visit_expr(subexpression)
223e47cc 666 }
7453a54e 667 ExprKind::Vec(ref subexpressions) => {
b039eaaf 668 walk_list!(visitor, visit_expr, subexpressions);
1a4d82fc 669 }
7453a54e 670 ExprKind::Repeat(ref element, ref count) => {
b039eaaf
SL
671 visitor.visit_expr(element);
672 visitor.visit_expr(count)
1a4d82fc 673 }
7453a54e 674 ExprKind::Struct(ref path, ref fields, ref optional_base) => {
1a4d82fc 675 visitor.visit_path(path, expression.id);
85aaf69f 676 for field in fields {
b039eaaf
SL
677 visitor.visit_ident(field.ident.span, field.ident.node);
678 visitor.visit_expr(&field.expr)
970d7e83 679 }
b039eaaf 680 walk_list!(visitor, visit_expr, optional_base);
223e47cc 681 }
7453a54e 682 ExprKind::Tup(ref subexpressions) => {
b039eaaf 683 walk_list!(visitor, visit_expr, subexpressions);
223e47cc 684 }
7453a54e 685 ExprKind::Call(ref callee_expression, ref arguments) => {
b039eaaf
SL
686 walk_list!(visitor, visit_expr, arguments);
687 visitor.visit_expr(callee_expression)
1a4d82fc 688 }
7453a54e 689 ExprKind::MethodCall(ref ident, ref types, ref arguments) => {
b039eaaf
SL
690 visitor.visit_ident(ident.span, ident.node);
691 walk_list!(visitor, visit_expr, arguments);
692 walk_list!(visitor, visit_ty, types);
223e47cc 693 }
7453a54e 694 ExprKind::Binary(_, ref left_expression, ref right_expression) => {
b039eaaf
SL
695 visitor.visit_expr(left_expression);
696 visitor.visit_expr(right_expression)
1a4d82fc 697 }
7453a54e 698 ExprKind::AddrOf(_, ref subexpression) | ExprKind::Unary(_, ref subexpression) => {
b039eaaf 699 visitor.visit_expr(subexpression)
1a4d82fc 700 }
7453a54e
SL
701 ExprKind::Lit(_) => {}
702 ExprKind::Cast(ref subexpression, ref typ) | ExprKind::Type(ref subexpression, ref typ) => {
b039eaaf
SL
703 visitor.visit_expr(subexpression);
704 visitor.visit_ty(typ)
1a4d82fc 705 }
7453a54e 706 ExprKind::If(ref head_expression, ref if_block, ref optional_else) => {
b039eaaf
SL
707 visitor.visit_expr(head_expression);
708 visitor.visit_block(if_block);
709 walk_list!(visitor, visit_expr, optional_else);
1a4d82fc 710 }
7453a54e 711 ExprKind::While(ref subexpression, ref block, opt_ident) => {
b039eaaf
SL
712 visitor.visit_expr(subexpression);
713 visitor.visit_block(block);
714 walk_opt_ident(visitor, expression.span, opt_ident)
1a4d82fc 715 }
7453a54e 716 ExprKind::IfLet(ref pattern, ref subexpression, ref if_block, ref optional_else) => {
b039eaaf
SL
717 visitor.visit_pat(pattern);
718 visitor.visit_expr(subexpression);
719 visitor.visit_block(if_block);
720 walk_list!(visitor, visit_expr, optional_else);
721 }
7453a54e 722 ExprKind::WhileLet(ref pattern, ref subexpression, ref block, opt_ident) => {
b039eaaf
SL
723 visitor.visit_pat(pattern);
724 visitor.visit_expr(subexpression);
725 visitor.visit_block(block);
726 walk_opt_ident(visitor, expression.span, opt_ident)
727 }
7453a54e 728 ExprKind::ForLoop(ref pattern, ref subexpression, ref block, opt_ident) => {
b039eaaf
SL
729 visitor.visit_pat(pattern);
730 visitor.visit_expr(subexpression);
731 visitor.visit_block(block);
732 walk_opt_ident(visitor, expression.span, opt_ident)
733 }
7453a54e 734 ExprKind::Loop(ref block, opt_ident) => {
b039eaaf
SL
735 visitor.visit_block(block);
736 walk_opt_ident(visitor, expression.span, opt_ident)
737 }
7453a54e 738 ExprKind::Match(ref subexpression, ref arms) => {
b039eaaf
SL
739 visitor.visit_expr(subexpression);
740 walk_list!(visitor, visit_arm, arms);
223e47cc 741 }
7453a54e 742 ExprKind::Closure(_, ref function_declaration, ref body) => {
e9174d1e 743 visitor.visit_fn(FnKind::Closure,
b039eaaf
SL
744 function_declaration,
745 body,
1a4d82fc
JJ
746 expression.span,
747 expression.id)
748 }
7453a54e
SL
749 ExprKind::Block(ref block) => visitor.visit_block(block),
750 ExprKind::Assign(ref left_hand_expression, ref right_hand_expression) => {
b039eaaf
SL
751 visitor.visit_expr(right_hand_expression);
752 visitor.visit_expr(left_hand_expression)
1a4d82fc 753 }
7453a54e 754 ExprKind::AssignOp(_, ref left_expression, ref right_expression) => {
b039eaaf
SL
755 visitor.visit_expr(right_expression);
756 visitor.visit_expr(left_expression)
223e47cc 757 }
7453a54e 758 ExprKind::Field(ref subexpression, ref ident) => {
b039eaaf
SL
759 visitor.visit_expr(subexpression);
760 visitor.visit_ident(ident.span, ident.node);
223e47cc 761 }
7453a54e 762 ExprKind::TupField(ref subexpression, _) => {
b039eaaf 763 visitor.visit_expr(subexpression);
223e47cc 764 }
7453a54e 765 ExprKind::Index(ref main_expression, ref index_expression) => {
b039eaaf
SL
766 visitor.visit_expr(main_expression);
767 visitor.visit_expr(index_expression)
223e47cc 768 }
54a0048b 769 ExprKind::Range(ref start, ref end, _) => {
b039eaaf
SL
770 walk_list!(visitor, visit_expr, start);
771 walk_list!(visitor, visit_expr, end);
223e47cc 772 }
7453a54e 773 ExprKind::Path(ref maybe_qself, ref path) => {
c34b1796
AL
774 if let Some(ref qself) = *maybe_qself {
775 visitor.visit_ty(&qself.ty);
776 }
1a4d82fc 777 visitor.visit_path(path, expression.id)
223e47cc 778 }
7453a54e 779 ExprKind::Break(ref opt_sp_ident) | ExprKind::Again(ref opt_sp_ident) => {
b039eaaf
SL
780 for sp_ident in opt_sp_ident {
781 visitor.visit_ident(sp_ident.span, sp_ident.node);
782 }
783 }
7453a54e 784 ExprKind::Ret(ref optional_expression) => {
b039eaaf 785 walk_list!(visitor, visit_expr, optional_expression);
1a4d82fc 786 }
7453a54e
SL
787 ExprKind::Mac(ref mac) => visitor.visit_mac(mac),
788 ExprKind::Paren(ref subexpression) => {
b039eaaf 789 visitor.visit_expr(subexpression)
1a4d82fc 790 }
7453a54e 791 ExprKind::InlineAsm(ref ia) => {
b039eaaf
SL
792 for &(_, ref input) in &ia.inputs {
793 visitor.visit_expr(&input)
1a4d82fc 794 }
9cc50fc6
SL
795 for output in &ia.outputs {
796 visitor.visit_expr(&output.expr)
1a4d82fc
JJ
797 }
798 }
54a0048b
SL
799 ExprKind::Try(ref subexpression) => {
800 visitor.visit_expr(subexpression)
801 }
1a4d82fc
JJ
802 }
803
804 visitor.visit_expr_post(expression)
805}
806
807pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) {
b039eaaf
SL
808 walk_list!(visitor, visit_pat, &arm.pats);
809 walk_list!(visitor, visit_expr, &arm.guard);
810 visitor.visit_expr(&arm.body);
811 walk_list!(visitor, visit_attribute, &arm.attrs);
223e47cc 812}
54a0048b
SL
813
814pub fn walk_vis<'v, V: Visitor<'v>>(visitor: &mut V, vis: &'v Visibility) {
815 match *vis {
816 Visibility::Restricted { ref path, id } => visitor.visit_path(path, id),
817 _ => {}
818 }
819}