blob: df49e71ce8cabcf6201d955f15daa06bebd60f4b [file] [log] [blame]
David Tolnay55337722016-09-11 12:58:56 -07001// Adapted from libsyntax.
2
3//! AST walker. Each overridden visit method has full control over what
4//! happens with its node, it can do its own traversal of the node's children,
5//! call `visit::walk_*` to apply the default traversal algorithm, or prevent
6//! deeper traversal by doing nothing.
7//!
8//! Note: it is an important invariant that the default visitor walks the body
9//! of a function in "execution order" (more concretely, reverse post-order
10//! with respect to the CFG implied by the AST), meaning that if AST node A may
11//! execute before AST node B, then A is visited first. The borrow checker in
12//! particular relies on this property.
13//!
14//! Note: walking an AST before macro expansion is probably a bad idea. For
15//! instance, a walker looking for item names in a module will miss all of
16//! those that are created by the expansion of a macro.
17
18use super::*;
19
20/// Each method of the Visitor trait is a hook to be potentially
21/// overridden. Each method's default implementation recursively visits
22/// the substructure of the input via the corresponding `walk` method;
23/// e.g. the `visit_mod` method by default calls `visit::walk_mod`.
24///
25/// If you want to ensure that your code handles every variant
26/// explicitly, you need to override each method. (And you also need
27/// to monitor future changes to `Visitor` in case a new method with a
28/// new default implementation gets introduced.)
29pub trait Visitor: Sized {
30 fn visit_ident(&mut self, _ident: &Ident) {}
David Tolnay0e837402016-12-22 17:25:55 -050031 fn visit_derive_input(&mut self, derive_input: &DeriveInput) {
32 walk_derive_input(self, derive_input)
David Tolnay55337722016-09-11 12:58:56 -070033 }
34 fn visit_ty(&mut self, ty: &Ty) {
35 walk_ty(self, ty)
36 }
37 fn visit_generics(&mut self, generics: &Generics) {
38 walk_generics(self, generics)
39 }
40 fn visit_ty_param_bound(&mut self, bound: &TyParamBound) {
41 walk_ty_param_bound(self, bound)
42 }
43 fn visit_poly_trait_ref(&mut self, trait_ref: &PolyTraitRef, modifier: &TraitBoundModifier) {
44 walk_poly_trait_ref(self, trait_ref, modifier)
45 }
46 fn visit_variant_data(&mut self, data: &VariantData, _ident: &Ident, _generics: &Generics) {
47 walk_variant_data(self, data)
48 }
49 fn visit_field(&mut self, field: &Field) {
50 walk_field(self, field)
51 }
52 fn visit_variant(&mut self, variant: &Variant, generics: &Generics) {
53 walk_variant(self, variant, generics)
54 }
55 fn visit_lifetime(&mut self, _lifetime: &Lifetime) {}
56 fn visit_lifetime_def(&mut self, lifetime: &LifetimeDef) {
57 walk_lifetime_def(self, lifetime)
58 }
59 fn visit_path(&mut self, path: &Path) {
60 walk_path(self, path)
61 }
62 fn visit_path_segment(&mut self, path_segment: &PathSegment) {
63 walk_path_segment(self, path_segment)
64 }
65 fn visit_path_parameters(&mut self, path_parameters: &PathParameters) {
66 walk_path_parameters(self, path_parameters)
67 }
68 fn visit_assoc_type_binding(&mut self, type_binding: &TypeBinding) {
69 walk_assoc_type_binding(self, type_binding)
70 }
71 fn visit_attribute(&mut self, _attr: &Attribute) {}
72 fn visit_fn_ret_ty(&mut self, ret_ty: &FunctionRetTy) {
73 walk_fn_ret_ty(self, ret_ty)
74 }
David Tolnay68eb4c32016-10-07 23:30:32 -070075 fn visit_const_expr(&mut self, expr: &ConstExpr) {
76 walk_const_expr(self, expr)
David Tolnay429168f2016-10-05 23:41:04 -070077 }
David Tolnay68eb4c32016-10-07 23:30:32 -070078 fn visit_lit(&mut self, _lit: &Lit) {}
Michael Layzellb52df322017-01-22 17:36:55 -050079
Michael Layzellb52df322017-01-22 17:36:55 -050080 fn visit_mac(&mut self, mac: &Mac) {
81 walk_mac(self, mac);
82 }
83
84 #[cfg(feature = "full")]
85 fn visit_crate(&mut self, _crate: &Crate) {
86 walk_crate(self, _crate);
87 }
88 #[cfg(feature = "full")]
89 fn visit_item(&mut self, item: &Item) {
90 walk_item(self, item);
91 }
92 #[cfg(feature = "full")]
93 fn visit_expr(&mut self, expr: &Expr) {
94 walk_expr(self, expr);
95 }
96 #[cfg(feature = "full")]
97 fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
98 walk_foreign_item(self, foreign_item);
99 }
100 #[cfg(feature = "full")]
101 fn visit_pat(&mut self, pat: &Pat) {
102 walk_pat(self, pat);
103 }
104 #[cfg(feature = "full")]
105 fn visit_fn_decl(&mut self, fn_decl: &FnDecl) {
106 walk_fn_decl(self, fn_decl);
107 }
108 #[cfg(feature = "full")]
109 fn visit_trait_item(&mut self, trait_item: &TraitItem) {
110 walk_trait_item(self, trait_item);
111 }
112 #[cfg(feature = "full")]
113 fn visit_impl_item(&mut self, impl_item: &ImplItem) {
114 walk_impl_item(self, impl_item);
115 }
116 #[cfg(feature = "full")]
117 fn visit_method_sig(&mut self, method_sig: &MethodSig) {
118 walk_method_sig(self, method_sig);
119 }
120 #[cfg(feature = "full")]
121 fn visit_stmt(&mut self, stmt: &Stmt) {
122 walk_stmt(self, stmt);
123 }
124 #[cfg(feature = "full")]
125 fn visit_local(&mut self, local: &Local) {
126 walk_local(self, local);
127 }
128 #[cfg(feature = "full")]
129 fn visit_view_path(&mut self, view_path: &ViewPath) {
130 walk_view_path(self, view_path);
131 }
David Tolnay55337722016-09-11 12:58:56 -0700132}
133
David Tolnay55337722016-09-11 12:58:56 -0700134macro_rules! walk_list {
David Tolnaybdae3642017-01-23 00:39:55 -0800135 ($visitor:expr, $method:ident, $list:expr $(, $extra_args:expr)*) => {
David Tolnay55337722016-09-11 12:58:56 -0700136 for elem in $list {
David Tolnaybdae3642017-01-23 00:39:55 -0800137 $visitor.$method(elem $(, $extra_args)*)
David Tolnay55337722016-09-11 12:58:56 -0700138 }
139 };
David Tolnay55337722016-09-11 12:58:56 -0700140}
141
142pub fn walk_opt_ident<V: Visitor>(visitor: &mut V, opt_ident: &Option<Ident>) {
143 if let Some(ref ident) = *opt_ident {
144 visitor.visit_ident(ident);
145 }
146}
147
148pub fn walk_lifetime_def<V: Visitor>(visitor: &mut V, lifetime_def: &LifetimeDef) {
149 visitor.visit_lifetime(&lifetime_def.lifetime);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700150 walk_list!(visitor, visit_lifetime, lifetime_def.bounds.items());
David Tolnay55337722016-09-11 12:58:56 -0700151}
152
153pub fn walk_poly_trait_ref<V>(visitor: &mut V, trait_ref: &PolyTraitRef, _: &TraitBoundModifier)
David Tolnaydaaf7742016-10-03 11:11:43 -0700154 where V: Visitor
David Tolnay55337722016-09-11 12:58:56 -0700155{
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700156 if let Some(ref bl) = trait_ref.bound_lifetimes {
157 walk_list!(visitor, visit_lifetime_def, bl.lifetimes.items());
158 }
David Tolnay55337722016-09-11 12:58:56 -0700159 visitor.visit_path(&trait_ref.trait_ref);
160}
161
David Tolnay0e837402016-12-22 17:25:55 -0500162pub fn walk_derive_input<V: Visitor>(visitor: &mut V, derive_input: &DeriveInput) {
163 visitor.visit_ident(&derive_input.ident);
164 visitor.visit_generics(&derive_input.generics);
165 match derive_input.body {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700166 Body::Enum(ref data) => {
167 walk_list!(visitor, visit_variant,
168 data.variants.items(),
169 &derive_input.generics);
David Tolnay55337722016-09-11 12:58:56 -0700170 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700171 Body::Struct(ref data) => {
172 visitor.visit_variant_data(&data.data, &derive_input.ident, &derive_input.generics);
David Tolnay55337722016-09-11 12:58:56 -0700173 }
174 }
David Tolnay0e837402016-12-22 17:25:55 -0500175 walk_list!(visitor, visit_attribute, &derive_input.attrs);
David Tolnay55337722016-09-11 12:58:56 -0700176}
177
178pub fn walk_variant<V>(visitor: &mut V, variant: &Variant, generics: &Generics)
David Tolnaydaaf7742016-10-03 11:11:43 -0700179 where V: Visitor
David Tolnay55337722016-09-11 12:58:56 -0700180{
181 visitor.visit_ident(&variant.ident);
182 visitor.visit_variant_data(&variant.data, &variant.ident, generics);
183 walk_list!(visitor, visit_attribute, &variant.attrs);
184}
185
186pub fn walk_ty<V: Visitor>(visitor: &mut V, ty: &Ty) {
Alex Crichton62a0a592017-05-22 13:58:53 -0700187 use ty::*;
188
David Tolnay55337722016-09-11 12:58:56 -0700189 match *ty {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700190 Ty::Slice(TySlice { ref ty, .. }) |
191 Ty::Paren(TyParen { ref ty, .. }) => visitor.visit_ty(ty),
192 Ty::Ptr(TyPtr { ref ty, .. }) => visitor.visit_ty(&ty.ty),
193 Ty::Rptr(TyRptr { ref lifetime, ref ty, .. }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -0700194 walk_list!(visitor, visit_lifetime, lifetime);
195 visitor.visit_ty(&ty.ty)
David Tolnay55337722016-09-11 12:58:56 -0700196 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700197 Ty::Never(_) | Ty::Infer(_) => {}
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700198 Ty::Tup(TyTup { ref tys, .. }) => {
199 walk_list!(visitor, visit_ty, tys.items());
David Tolnay55337722016-09-11 12:58:56 -0700200 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700201 Ty::BareFn(TyBareFn { ref ty }) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700202 if let Some(ref l) = ty.lifetimes {
203 walk_list!(visitor, visit_lifetime_def, l.lifetimes.items());
204 }
205 for argument in ty.inputs.items() {
206 if let Some((ref name, _)) = argument.name {
207 visitor.visit_ident(name);
208 }
David Tolnay1391b522016-10-03 21:05:45 -0700209 visitor.visit_ty(&argument.ty)
210 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700211 visitor.visit_fn_ret_ty(&ty.output)
David Tolnay55337722016-09-11 12:58:56 -0700212 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700213 Ty::Path(TyPath { ref qself, ref path }) => {
214 if let Some(ref qself) = *qself {
David Tolnay55337722016-09-11 12:58:56 -0700215 visitor.visit_ty(&qself.ty);
216 }
217 visitor.visit_path(path);
218 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700219 Ty::Array(TyArray { ref ty, ref amt, .. }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -0700220 visitor.visit_ty(ty);
221 visitor.visit_const_expr(amt);
David Tolnay55337722016-09-11 12:58:56 -0700222 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700223 Ty::TraitObject(TyTraitObject { ref bounds, .. }) |
224 Ty::ImplTrait(TyImplTrait { ref bounds, .. }) => {
225 walk_list!(visitor, visit_ty_param_bound, bounds.items());
David Tolnay55337722016-09-11 12:58:56 -0700226 }
Michael Layzellb52df322017-01-22 17:36:55 -0500227 Ty::Mac(ref mac) => {
David Tolnay3f36a0a2017-01-23 17:59:46 -0800228 visitor.visit_mac(mac);
Michael Layzellb52df322017-01-22 17:36:55 -0500229 }
David Tolnay55337722016-09-11 12:58:56 -0700230 }
231}
232
233pub fn walk_path<V: Visitor>(visitor: &mut V, path: &Path) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700234 for segment in path.segments.items() {
David Tolnay55337722016-09-11 12:58:56 -0700235 visitor.visit_path_segment(segment);
236 }
237}
238
239pub fn walk_path_segment<V: Visitor>(visitor: &mut V, segment: &PathSegment) {
240 visitor.visit_ident(&segment.ident);
241 visitor.visit_path_parameters(&segment.parameters);
242}
243
244pub fn walk_path_parameters<V>(visitor: &mut V, path_parameters: &PathParameters)
David Tolnaydaaf7742016-10-03 11:11:43 -0700245 where V: Visitor
David Tolnay55337722016-09-11 12:58:56 -0700246{
247 match *path_parameters {
248 PathParameters::AngleBracketed(ref data) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700249 walk_list!(visitor, visit_ty, data.types.items());
250 walk_list!(visitor, visit_lifetime, data.lifetimes.items());
251 walk_list!(visitor, visit_assoc_type_binding, data.bindings.items());
David Tolnay55337722016-09-11 12:58:56 -0700252 }
253 PathParameters::Parenthesized(ref data) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700254 walk_list!(visitor, visit_ty, data.inputs.items());
255 visitor.visit_fn_ret_ty(&data.output);
David Tolnay55337722016-09-11 12:58:56 -0700256 }
257 }
258}
259
260pub fn walk_assoc_type_binding<V: Visitor>(visitor: &mut V, type_binding: &TypeBinding) {
261 visitor.visit_ident(&type_binding.ident);
262 visitor.visit_ty(&type_binding.ty);
263}
264
265pub fn walk_ty_param_bound<V: Visitor>(visitor: &mut V, bound: &TyParamBound) {
266 match *bound {
267 TyParamBound::Trait(ref ty, ref modifier) => {
268 visitor.visit_poly_trait_ref(ty, modifier);
269 }
270 TyParamBound::Region(ref lifetime) => {
271 visitor.visit_lifetime(lifetime);
272 }
273 }
274}
275
276pub fn walk_generics<V: Visitor>(visitor: &mut V, generics: &Generics) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700277 for param in generics.ty_params.items() {
David Tolnay55337722016-09-11 12:58:56 -0700278 visitor.visit_ident(&param.ident);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700279 walk_list!(visitor, visit_ty_param_bound, param.bounds.items());
David Tolnay55337722016-09-11 12:58:56 -0700280 walk_list!(visitor, visit_ty, &param.default);
281 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700282 walk_list!(visitor, visit_lifetime_def, generics.lifetimes.items());
283 for predicate in generics.where_clause.predicates.items() {
David Tolnay55337722016-09-11 12:58:56 -0700284 match *predicate {
David Tolnaydaaf7742016-10-03 11:11:43 -0700285 WherePredicate::BoundPredicate(WhereBoundPredicate { ref bounded_ty,
286 ref bounds,
287 ref bound_lifetimes,
288 .. }) => {
David Tolnay55337722016-09-11 12:58:56 -0700289 visitor.visit_ty(bounded_ty);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700290 walk_list!(visitor, visit_ty_param_bound, bounds.items());
291 if let Some(ref l) = *bound_lifetimes {
292 walk_list!(visitor, visit_lifetime_def, l.lifetimes.items());
293 }
David Tolnay55337722016-09-11 12:58:56 -0700294 }
David Tolnaydaaf7742016-10-03 11:11:43 -0700295 WherePredicate::RegionPredicate(WhereRegionPredicate { ref lifetime,
296 ref bounds,
297 .. }) => {
David Tolnay55337722016-09-11 12:58:56 -0700298 visitor.visit_lifetime(lifetime);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700299 walk_list!(visitor, visit_lifetime, bounds.items());
David Tolnay55337722016-09-11 12:58:56 -0700300 }
David Tolnay05120ef2017-03-12 18:29:26 -0700301 WherePredicate::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty, .. }) => {
David Tolnayfa23f572017-01-23 00:19:11 -0800302 visitor.visit_ty(lhs_ty);
303 visitor.visit_ty(rhs_ty);
304 }
David Tolnay55337722016-09-11 12:58:56 -0700305 }
306 }
307}
308
309pub fn walk_fn_ret_ty<V: Visitor>(visitor: &mut V, ret_ty: &FunctionRetTy) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700310 if let FunctionRetTy::Ty(ref output_ty, _) = *ret_ty {
David Tolnay55337722016-09-11 12:58:56 -0700311 visitor.visit_ty(output_ty)
312 }
313}
314
David Tolnay55337722016-09-11 12:58:56 -0700315pub fn walk_variant_data<V: Visitor>(visitor: &mut V, data: &VariantData) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700316 let fields = match *data {
317 VariantData::Struct(ref f, _) |
318 VariantData::Tuple(ref f, _) => f,
319 VariantData::Unit => return,
320 };
321 walk_list!(visitor, visit_field, fields.items());
David Tolnay55337722016-09-11 12:58:56 -0700322}
323
324pub fn walk_field<V: Visitor>(visitor: &mut V, field: &Field) {
325 walk_opt_ident(visitor, &field.ident);
326 visitor.visit_ty(&field.ty);
327 walk_list!(visitor, visit_attribute, &field.attrs);
328}
David Tolnay429168f2016-10-05 23:41:04 -0700329
David Tolnay68eb4c32016-10-07 23:30:32 -0700330pub fn walk_const_expr<V: Visitor>(visitor: &mut V, len: &ConstExpr) {
Alex Crichton62a0a592017-05-22 13:58:53 -0700331 use constant::*;
332 use constant::ConstExpr::*;
333
David Tolnay429168f2016-10-05 23:41:04 -0700334 match *len {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700335 Call(ConstCall { ref func, ref args, .. }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -0700336 visitor.visit_const_expr(func);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700337 walk_list!(visitor, visit_const_expr, args.items());
David Tolnay68eb4c32016-10-07 23:30:32 -0700338 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700339 Binary(ConstBinary { ref left, ref right, .. }) => {
David Tolnay68eb4c32016-10-07 23:30:32 -0700340 visitor.visit_const_expr(left);
341 visitor.visit_const_expr(right);
342 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700343 Lit(ref lit) => {
David Tolnay68eb4c32016-10-07 23:30:32 -0700344 visitor.visit_lit(lit);
345 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700346 Cast(ConstCast { ref expr, ref ty, .. }) => {
David Tolnay68eb4c32016-10-07 23:30:32 -0700347 visitor.visit_const_expr(expr);
348 visitor.visit_ty(ty);
349 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700350 Path(ref path) => {
David Tolnay429168f2016-10-05 23:41:04 -0700351 visitor.visit_path(path);
352 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700353 Index(ConstIndex { ref expr, ref index, .. }) => {
David Tolnay67588752016-10-30 12:23:10 -0700354 visitor.visit_const_expr(expr);
355 visitor.visit_const_expr(index);
356 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700357 Unary(ConstUnary { ref expr, .. }) |
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700358 Paren(ConstParen { ref expr, .. }) => {
David Tolnaye7b0d322016-10-30 10:27:23 -0700359 visitor.visit_const_expr(expr);
360 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700361 Other(ref other) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500362 #[cfg(feature = "full")]
363 fn walk_other<V: Visitor>(visitor: &mut V, other: &Expr) {
364 visitor.visit_expr(other);
365 }
366 #[cfg(not(feature = "full"))]
367 fn walk_other<V: Visitor>(_: &mut V, _: &super::constant::Other) {}
368 walk_other(visitor, other);
369 }
370 }
371}
372
Michael Layzellb52df322017-01-22 17:36:55 -0500373pub fn walk_mac<V: Visitor>(visitor: &mut V, mac: &Mac) {
374 visitor.visit_path(&mac.path);
375}
376
377#[cfg(feature = "full")]
378pub fn walk_crate<V: Visitor>(visitor: &mut V, _crate: &Crate) {
379 walk_list!(visitor, visit_attribute, &_crate.attrs);
380 walk_list!(visitor, visit_item, &_crate.items);
381}
382
383#[cfg(feature = "full")]
384pub fn walk_item<V: Visitor>(visitor: &mut V, item: &Item) {
Alex Crichton62a0a592017-05-22 13:58:53 -0700385 use item::*;
386
Michael Layzellb52df322017-01-22 17:36:55 -0500387 visitor.visit_ident(&item.ident);
388 walk_list!(visitor, visit_attribute, &item.attrs);
389 match item.node {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700390 ItemKind::ExternCrate(ItemExternCrate { ref original, .. }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -0700391 walk_opt_ident(visitor, original);
Michael Layzellb52df322017-01-22 17:36:55 -0500392 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700393 ItemKind::Use(ItemUse { ref path, .. }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -0700394 visitor.visit_view_path(path);
Michael Layzellb52df322017-01-22 17:36:55 -0500395 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700396 ItemKind::Static(ItemStatic { ref ty, ref expr, .. }) |
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700397 ItemKind::Const(ItemConst { ref ty, ref expr, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500398 visitor.visit_ty(ty);
399 visitor.visit_expr(expr);
400 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700401 ItemKind::Fn(ItemFn { ref decl, ref block, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500402 visitor.visit_fn_decl(decl);
Alex Crichton62a0a592017-05-22 13:58:53 -0700403 walk_list!(visitor, visit_stmt, &block.stmts);
Michael Layzellb52df322017-01-22 17:36:55 -0500404 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700405 ItemKind::Mod(ItemMod { ref items, .. }) => {
406 if let Some((ref items, _)) = *items {
Michael Layzellb52df322017-01-22 17:36:55 -0500407 walk_list!(visitor, visit_item, items);
408 }
409 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700410 ItemKind::ForeignMod(ItemForeignMod { ref items, .. }) => {
411 walk_list!(visitor, visit_foreign_item, items);
Michael Layzellb52df322017-01-22 17:36:55 -0500412 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700413 ItemKind::Ty(ItemTy { ref ty, ref generics, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500414 visitor.visit_ty(ty);
415 visitor.visit_generics(generics);
416 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700417 ItemKind::Enum(ItemEnum { ref variants, ref generics, ..}) => {
418 walk_list!(visitor, visit_variant, variants.items(), generics);
Michael Layzellb52df322017-01-22 17:36:55 -0500419 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700420 ItemKind::Struct(ItemStruct { ref data, ref generics, .. }) |
421 ItemKind::Union(ItemUnion { ref data, ref generics, .. }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -0700422 visitor.visit_variant_data(data, &item.ident, generics);
Michael Layzellb52df322017-01-22 17:36:55 -0500423 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700424 ItemKind::Trait(ItemTrait {
425 ref generics,
426 ref supertraits,
427 ref items,
428 ..
429 }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500430 visitor.visit_generics(generics);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700431 walk_list!(visitor, visit_ty_param_bound, supertraits.items());
Alex Crichton62a0a592017-05-22 13:58:53 -0700432 walk_list!(visitor, visit_trait_item, items);
Michael Layzellb52df322017-01-22 17:36:55 -0500433 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700434 ItemKind::DefaultImpl(ItemDefaultImpl { ref path, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500435 visitor.visit_path(path);
436 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700437 ItemKind::Impl(ItemImpl {
438 ref generics,
439 ref trait_,
440 ref self_ty,
441 ref items,
442 ..
443 }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500444 visitor.visit_generics(generics);
Alex Crichton62a0a592017-05-22 13:58:53 -0700445 if let Some(ref path) = *trait_ {
Michael Layzellb52df322017-01-22 17:36:55 -0500446 visitor.visit_path(path);
447 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700448 visitor.visit_ty(self_ty);
449 walk_list!(visitor, visit_impl_item, items);
Michael Layzellb52df322017-01-22 17:36:55 -0500450 }
David Tolnay05120ef2017-03-12 18:29:26 -0700451 ItemKind::Mac(ref mac) => visitor.visit_mac(mac),
Michael Layzellb52df322017-01-22 17:36:55 -0500452 }
453}
454
455#[cfg(feature = "full")]
David Tolnay02a8d472017-02-19 12:59:44 -0800456#[cfg_attr(feature = "cargo-clippy", allow(cyclomatic_complexity))]
Michael Layzellb52df322017-01-22 17:36:55 -0500457pub fn walk_expr<V: Visitor>(visitor: &mut V, expr: &Expr) {
Alex Crichton62a0a592017-05-22 13:58:53 -0700458 use expr::*;
459 use expr::ExprKind::*;
460
Michael Layzellb52df322017-01-22 17:36:55 -0500461 walk_list!(visitor, visit_attribute, &expr.attrs);
462 match expr.node {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700463 InPlace(ExprInPlace { ref place, ref value, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500464 visitor.visit_expr(place);
465 visitor.visit_expr(value);
466 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700467 Call(ExprCall { ref func, ref args, .. }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -0700468 visitor.visit_expr(func);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700469 walk_list!(visitor, visit_expr, args.items());
Michael Layzellb52df322017-01-22 17:36:55 -0500470 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700471 MethodCall(ExprMethodCall { ref method, ref typarams, ref args, .. }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -0700472 visitor.visit_ident(method);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700473 walk_list!(visitor, visit_ty, typarams.items());
474 walk_list!(visitor, visit_expr, args.items());
Michael Layzellb52df322017-01-22 17:36:55 -0500475 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700476 Array(ExprArray { ref exprs, ..}) |
477 Tup(ExprTup { args: ref exprs, .. }) => {
478 walk_list!(visitor, visit_expr, exprs.items());
Michael Layzellb52df322017-01-22 17:36:55 -0500479 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700480 Lit(ref lit) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500481 visitor.visit_lit(lit);
482 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700483 Cast(ExprCast { ref expr, ref ty, .. }) |
484 Type(ExprType { ref expr, ref ty, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500485 visitor.visit_expr(expr);
486 visitor.visit_ty(ty);
487 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700488 If(ExprIf { ref cond, ref if_true, ref if_false, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500489 visitor.visit_expr(cond);
Alex Crichton62a0a592017-05-22 13:58:53 -0700490 walk_list!(visitor, visit_stmt, &if_true.stmts);
491 if let Some(ref alt) = *if_false {
Michael Layzellb52df322017-01-22 17:36:55 -0500492 visitor.visit_expr(alt);
493 }
494 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700495 IfLet(ExprIfLet { ref pat, ref expr, ref if_true, ref if_false, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500496 visitor.visit_pat(pat);
Alex Crichton62a0a592017-05-22 13:58:53 -0700497 visitor.visit_expr(expr);
498 walk_list!(visitor, visit_stmt, &if_true.stmts);
499 if let Some(ref alt) = *if_false {
Michael Layzellb52df322017-01-22 17:36:55 -0500500 visitor.visit_expr(alt);
501 }
502 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700503 While(ExprWhile { ref cond, ref body, ref label, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500504 visitor.visit_expr(cond);
505 walk_list!(visitor, visit_stmt, &body.stmts);
506 walk_opt_ident(visitor, label);
507 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700508 WhileLet(ExprWhileLet { ref pat, ref expr, ref body, ref label, .. }) |
509 ForLoop(ExprForLoop { ref pat, ref expr, ref body, ref label, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500510 visitor.visit_pat(pat);
511 visitor.visit_expr(expr);
512 walk_list!(visitor, visit_stmt, &body.stmts);
513 walk_opt_ident(visitor, label);
514 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700515 Loop(ExprLoop { ref body, ref label, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500516 walk_list!(visitor, visit_stmt, &body.stmts);
517 walk_opt_ident(visitor, label);
518 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700519 Match(ExprMatch { ref expr, ref arms, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500520 visitor.visit_expr(expr);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700521 for &Arm { ref attrs, ref pats, ref guard, ref body, .. } in arms {
Michael Layzellb52df322017-01-22 17:36:55 -0500522 walk_list!(visitor, visit_attribute, attrs);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700523 walk_list!(visitor, visit_pat, pats.items());
Michael Layzellb52df322017-01-22 17:36:55 -0500524 if let Some(ref guard) = *guard {
525 visitor.visit_expr(guard);
526 }
527 visitor.visit_expr(body);
528 }
529 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700530 Closure(ExprClosure { ref decl, ref body, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500531 visitor.visit_fn_decl(decl);
Alex Crichton62a0a592017-05-22 13:58:53 -0700532 visitor.visit_expr(body);
Michael Layzellb52df322017-01-22 17:36:55 -0500533 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700534 Catch(ExprCatch { ref block, .. }) |
Alex Crichton62a0a592017-05-22 13:58:53 -0700535 Block(ExprBlock { ref block, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500536 walk_list!(visitor, visit_stmt, &block.stmts);
537 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700538 Binary(ExprBinary { ref left, ref right, .. }) |
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700539 Assign(ExprAssign { ref left, ref right, .. }) |
Alex Crichton62a0a592017-05-22 13:58:53 -0700540 AssignOp(ExprAssignOp { ref left, ref right, .. }) => {
541 visitor.visit_expr(left);
542 visitor.visit_expr(right);
Michael Layzellb52df322017-01-22 17:36:55 -0500543 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700544 Field(ExprField { ref expr, ref field, .. }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -0700545 visitor.visit_expr(expr);
Michael Layzellb52df322017-01-22 17:36:55 -0500546 visitor.visit_ident(field);
547 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700548 Index(ExprIndex { ref expr, ref index, .. }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -0700549 visitor.visit_expr(expr);
550 visitor.visit_expr(index);
Michael Layzellb52df322017-01-22 17:36:55 -0500551 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700552 Range(ExprRange { ref from, ref to, .. }) => {
553 if let Some(ref start) = *from {
Michael Layzellb52df322017-01-22 17:36:55 -0500554 visitor.visit_expr(start);
555 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700556 if let Some(ref end) = *to {
Michael Layzellb52df322017-01-22 17:36:55 -0500557 visitor.visit_expr(end);
558 }
559 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700560 Path(ExprPath { ref qself, ref path }) => {
561 if let Some(ref qself) = *qself {
Michael Layzellb52df322017-01-22 17:36:55 -0500562 visitor.visit_ty(&qself.ty);
563 }
564 visitor.visit_path(path);
565 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700566 Break(ExprBreak { ref label, ref expr, .. }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -0700567 walk_opt_ident(visitor, label);
568 if let Some(ref expr) = *expr {
Michael Layzellb52df322017-01-22 17:36:55 -0500569 visitor.visit_expr(expr);
570 }
571 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700572 Continue(ExprContinue { ref label, .. }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -0700573 walk_opt_ident(visitor, label);
Michael Layzellb52df322017-01-22 17:36:55 -0500574 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700575 Ret(ExprRet { ref expr, .. }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -0700576 if let Some(ref expr) = *expr {
Michael Layzellb52df322017-01-22 17:36:55 -0500577 visitor.visit_expr(expr);
578 }
579 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700580 Mac(ref mac) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500581 visitor.visit_mac(mac);
582 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700583 Struct(ExprStruct { ref path, ref fields, ref rest, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500584 visitor.visit_path(path);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700585 for &FieldValue { ref ident, ref expr, .. } in fields.items() {
Michael Layzellb52df322017-01-22 17:36:55 -0500586 visitor.visit_ident(ident);
587 visitor.visit_expr(expr);
588 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700589 if let Some(ref base) = *rest {
Michael Layzellb52df322017-01-22 17:36:55 -0500590 visitor.visit_expr(base);
591 }
592 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700593 Repeat(ExprRepeat { ref expr, ref amt, .. }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -0700594 visitor.visit_expr(expr);
595 visitor.visit_expr(amt);
Michael Layzellb52df322017-01-22 17:36:55 -0500596 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700597 TupField(ExprTupField { ref expr, .. }) |
598 Unary(ExprUnary { ref expr, .. }) |
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700599 Box(ExprBox { ref expr, .. }) |
Alex Crichton62a0a592017-05-22 13:58:53 -0700600 AddrOf(ExprAddrOf { ref expr, .. }) |
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700601 Paren(ExprParen { ref expr, .. }) |
602 Try(ExprTry { ref expr, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500603 visitor.visit_expr(expr);
604 }
605 }
606}
607
608#[cfg(feature = "full")]
609pub fn walk_foreign_item<V: Visitor>(visitor: &mut V, foreign_item: &ForeignItem) {
Alex Crichton62a0a592017-05-22 13:58:53 -0700610 use item::*;
611
Michael Layzellb52df322017-01-22 17:36:55 -0500612 visitor.visit_ident(&foreign_item.ident);
613 walk_list!(visitor, visit_attribute, &foreign_item.attrs);
614 match foreign_item.node {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700615 ForeignItemKind::Fn(ForeignItemFn { ref decl, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500616 visitor.visit_fn_decl(decl);
Michael Layzellb52df322017-01-22 17:36:55 -0500617 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700618 ForeignItemKind::Static(ForeignItemStatic { ref ty, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500619 visitor.visit_ty(ty);
620 }
621 }
622}
623
624#[cfg(feature = "full")]
625pub fn walk_pat<V: Visitor>(visitor: &mut V, pat: &Pat) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700626 use expr::*;
627
Michael Layzellb52df322017-01-22 17:36:55 -0500628 match *pat {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700629 Pat::Wild(_) => {}
630 Pat::Ident(PatIdent { ref ident, ref subpat, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500631 visitor.visit_ident(ident);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700632 if let Some(ref pat) = *subpat {
Michael Layzellb52df322017-01-22 17:36:55 -0500633 visitor.visit_pat(pat);
634 }
635 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700636 Pat::Struct(PatStruct { ref path, ref fields, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500637 visitor.visit_path(path);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700638 for &FieldPat { ref ident, ref pat, .. } in fields.items() {
Michael Layzellb52df322017-01-22 17:36:55 -0500639 visitor.visit_ident(ident);
640 visitor.visit_pat(pat);
641 }
642 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700643 Pat::TupleStruct(PatTupleStruct { ref path, ref pat, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500644 visitor.visit_path(path);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700645 walk_list!(visitor, visit_pat, pat.pats.items());
Michael Layzellb52df322017-01-22 17:36:55 -0500646 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700647 Pat::Path(PatPath { ref qself, ref path }) => {
648 if let Some(ref qself) = *qself {
Michael Layzellb52df322017-01-22 17:36:55 -0500649 visitor.visit_ty(&qself.ty);
650 }
651 visitor.visit_path(path);
652 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700653 Pat::Tuple(PatTuple { ref pats, .. }) => {
654 walk_list!(visitor, visit_pat, pats.items());
Michael Layzellb52df322017-01-22 17:36:55 -0500655 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700656 Pat::Box(PatBox { ref pat, .. }) |
657 Pat::Ref(PatRef { ref pat, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500658 visitor.visit_pat(pat);
659 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700660 Pat::Lit(PatLit { ref expr }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500661 visitor.visit_expr(expr);
662 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700663 Pat::Range(PatRange { ref lo, ref hi, .. }) => {
664 visitor.visit_expr(lo);
665 visitor.visit_expr(hi);
Michael Layzellb52df322017-01-22 17:36:55 -0500666 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700667 Pat::Slice(PatSlice { ref front, ref middle, ref back, .. }) => {
668 walk_list!(visitor, visit_pat, front.items());
669 if let Some(ref mid) = *middle {
Michael Layzellb52df322017-01-22 17:36:55 -0500670 visitor.visit_pat(mid);
671 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700672 walk_list!(visitor, visit_pat, back.items());
Michael Layzellb52df322017-01-22 17:36:55 -0500673 }
674 Pat::Mac(ref mac) => {
675 visitor.visit_mac(mac);
676 }
677 }
678}
679
680#[cfg(feature = "full")]
681pub fn walk_fn_decl<V: Visitor>(visitor: &mut V, fn_decl: &FnDecl) {
Alex Crichton62a0a592017-05-22 13:58:53 -0700682 use item::*;
683
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700684 for input in fn_decl.inputs.items() {
Michael Layzellb52df322017-01-22 17:36:55 -0500685 match *input {
Alex Crichton62a0a592017-05-22 13:58:53 -0700686 FnArg::SelfRef(_) |
David Tolnay05120ef2017-03-12 18:29:26 -0700687 FnArg::SelfValue(_) => {}
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700688 FnArg::Captured(ArgCaptured { ref pat, ref ty, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500689 visitor.visit_pat(pat);
690 visitor.visit_ty(ty);
691 }
692 FnArg::Ignored(ref ty) => {
693 visitor.visit_ty(ty);
694 }
695 }
696 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700697 visitor.visit_generics(&fn_decl.generics);
Michael Layzellb52df322017-01-22 17:36:55 -0500698 visitor.visit_fn_ret_ty(&fn_decl.output);
699}
700
701#[cfg(feature = "full")]
702pub fn walk_trait_item<V: Visitor>(visitor: &mut V, trait_item: &TraitItem) {
Alex Crichton62a0a592017-05-22 13:58:53 -0700703 use item::*;
704
Michael Layzellb52df322017-01-22 17:36:55 -0500705 visitor.visit_ident(&trait_item.ident);
706 walk_list!(visitor, visit_attribute, &trait_item.attrs);
707 match trait_item.node {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700708 TraitItemKind::Const(TraitItemConst { ref ty, ref default, ..}) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500709 visitor.visit_ty(ty);
Alex Crichton62a0a592017-05-22 13:58:53 -0700710 if let Some(ref expr) = *default {
Michael Layzellb52df322017-01-22 17:36:55 -0500711 visitor.visit_expr(expr);
712 }
713 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700714 TraitItemKind::Method(TraitItemMethod { ref sig, ref default, .. }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -0700715 visitor.visit_method_sig(sig);
716 if let Some(ref block) = *default {
Michael Layzellb52df322017-01-22 17:36:55 -0500717 walk_list!(visitor, visit_stmt, &block.stmts);
718 }
719 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700720 TraitItemKind::Type(TraitItemType { ref bounds, ref default, .. }) => {
721 walk_list!(visitor, visit_ty_param_bound, bounds.items());
Alex Crichton62a0a592017-05-22 13:58:53 -0700722 if let Some(ref ty) = *default {
Michael Layzellb52df322017-01-22 17:36:55 -0500723 visitor.visit_ty(ty);
724 }
725 }
726 TraitItemKind::Macro(ref mac) => {
727 visitor.visit_mac(mac);
728 }
729 }
730}
731
732#[cfg(feature = "full")]
733pub fn walk_impl_item<V: Visitor>(visitor: &mut V, impl_item: &ImplItem) {
Alex Crichton62a0a592017-05-22 13:58:53 -0700734 use item::*;
735
Michael Layzellb52df322017-01-22 17:36:55 -0500736 visitor.visit_ident(&impl_item.ident);
737 walk_list!(visitor, visit_attribute, &impl_item.attrs);
738 match impl_item.node {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700739 ImplItemKind::Const(ImplItemConst { ref ty, ref expr, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500740 visitor.visit_ty(ty);
741 visitor.visit_expr(expr);
742 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700743 ImplItemKind::Method(ImplItemMethod { ref sig, ref block, .. }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -0700744 visitor.visit_method_sig(sig);
Michael Layzellb52df322017-01-22 17:36:55 -0500745 walk_list!(visitor, visit_stmt, &block.stmts);
746 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700747 ImplItemKind::Type(ImplItemType { ref ty, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500748 visitor.visit_ty(ty);
749 }
750 ImplItemKind::Macro(ref mac) => {
751 visitor.visit_mac(mac);
752 }
753 }
754}
755
756#[cfg(feature = "full")]
757pub fn walk_method_sig<V: Visitor>(visitor: &mut V, method_sig: &MethodSig) {
758 visitor.visit_fn_decl(&method_sig.decl);
Michael Layzellb52df322017-01-22 17:36:55 -0500759}
760
761#[cfg(feature = "full")]
762pub fn walk_stmt<V: Visitor>(visitor: &mut V, stmt: &Stmt) {
763 match *stmt {
764 Stmt::Local(ref local) => {
765 visitor.visit_local(local);
766 }
767 Stmt::Item(ref item) => {
768 visitor.visit_item(item);
769 }
770 Stmt::Expr(ref expr) |
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700771 Stmt::Semi(ref expr, _) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500772 visitor.visit_expr(expr);
773 }
774 Stmt::Mac(ref details) => {
775 let (ref mac, _, ref attrs) = **details;
776 visitor.visit_mac(mac);
777 walk_list!(visitor, visit_attribute, attrs);
778 }
779 }
780}
781
782#[cfg(feature = "full")]
783pub fn walk_local<V: Visitor>(visitor: &mut V, local: &Local) {
784 visitor.visit_pat(&local.pat);
785 if let Some(ref ty) = local.ty {
786 visitor.visit_ty(ty);
787 }
788 if let Some(ref init) = local.init {
789 visitor.visit_expr(init);
790 }
791 walk_list!(visitor, visit_attribute, &local.attrs);
792}
793
794#[cfg(feature = "full")]
795pub fn walk_view_path<V: Visitor>(visitor: &mut V, view_path: &ViewPath) {
Alex Crichton62a0a592017-05-22 13:58:53 -0700796 use item::*;
Michael Layzellb52df322017-01-22 17:36:55 -0500797 match *view_path {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700798 ViewPath::Simple(PathSimple { ref path, ref rename, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500799 visitor.visit_path(path);
Alex Crichton62a0a592017-05-22 13:58:53 -0700800 walk_opt_ident(visitor, rename);
Michael Layzellb52df322017-01-22 17:36:55 -0500801 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700802 ViewPath::Glob(PathGlob { ref path, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500803 visitor.visit_path(path);
804 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700805 ViewPath::List(PathList { ref path, ref items, .. }) => {
Michael Layzellb52df322017-01-22 17:36:55 -0500806 visitor.visit_path(path);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700807 for &PathListItem { ref name, ref rename, .. } in items.items() {
Michael Layzellb52df322017-01-22 17:36:55 -0500808 visitor.visit_ident(name);
809 walk_opt_ident(visitor, rename);
810 }
811 }
David Tolnay429168f2016-10-05 23:41:04 -0700812 }
813}