]>
Commit | Line | Data |
---|---|---|
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 | 26 | use abi::Abi; |
223e47cc | 27 | use ast::*; |
3157f602 XL |
28 | use syntax_pos::Span; |
29 | use codemap::Spanned; | |
abe05a73 XL |
30 | use parse::token::Token; |
31 | use tokenstream::{TokenTree, TokenStream}; | |
1a4d82fc | 32 | |
e9174d1e | 33 | #[derive(Copy, Clone, PartialEq, Eq)] |
1a4d82fc JJ |
34 | pub enum FnKind<'a> { |
35 | /// fn foo() or extern "Abi" fn foo() | |
abe05a73 | 36 | ItemFn(Ident, Unsafety, Spanned<Constness>, Abi, &'a Visibility, &'a Block), |
1a4d82fc JJ |
37 | |
38 | /// fn foo(&self) | |
476ff2be | 39 | Method(Ident, &'a MethodSig, Option<&'a Visibility>, &'a Block), |
1a4d82fc | 40 | |
476ff2be SL |
41 | /// |x, y| body |
42 | Closure(&'a Expr), | |
1a4d82fc JJ |
43 | } |
44 | ||
45 | /// Each method of the Visitor trait is a hook to be potentially | |
46 | /// overridden. Each method's default implementation recursively visits | |
47 | /// the substructure of the input via the corresponding `walk` method; | |
48 | /// e.g. the `visit_mod` method by default calls `visit::walk_mod`. | |
49 | /// | |
50 | /// If you want to ensure that your code handles every variant | |
51 | /// explicitly, you need to override each method. (And you also need | |
52 | /// to monitor future changes to `Visitor` in case a new method with a | |
53 | /// new default implementation gets introduced.) | |
476ff2be | 54 | pub trait Visitor<'ast>: Sized { |
1a4d82fc JJ |
55 | fn visit_name(&mut self, _span: Span, _name: Name) { |
56 | // Nothing to do. | |
57 | } | |
58 | fn visit_ident(&mut self, span: Span, ident: Ident) { | |
b039eaaf | 59 | walk_ident(self, span, ident); |
1a4d82fc | 60 | } |
7cac9316 XL |
61 | fn visit_mod(&mut self, m: &'ast Mod, _s: Span, _attrs: &[Attribute], _n: NodeId) { |
62 | walk_mod(self, m); | |
63 | } | |
476ff2be | 64 | fn visit_foreign_item(&mut self, i: &'ast ForeignItem) { walk_foreign_item(self, i) } |
cc61c64b | 65 | fn visit_global_asm(&mut self, ga: &'ast GlobalAsm) { walk_global_asm(self, ga) } |
476ff2be SL |
66 | fn visit_item(&mut self, i: &'ast Item) { walk_item(self, i) } |
67 | fn visit_local(&mut self, l: &'ast Local) { walk_local(self, l) } | |
68 | fn visit_block(&mut self, b: &'ast Block) { walk_block(self, b) } | |
69 | fn visit_stmt(&mut self, s: &'ast Stmt) { walk_stmt(self, s) } | |
70 | fn visit_arm(&mut self, a: &'ast Arm) { walk_arm(self, a) } | |
71 | fn visit_pat(&mut self, p: &'ast Pat) { walk_pat(self, p) } | |
72 | fn visit_expr(&mut self, ex: &'ast Expr) { walk_expr(self, ex) } | |
73 | fn visit_expr_post(&mut self, _ex: &'ast Expr) { } | |
74 | fn visit_ty(&mut self, t: &'ast Ty) { walk_ty(self, t) } | |
ff7c6d11 | 75 | fn visit_generic_param(&mut self, param: &'ast GenericParam) { walk_generic_param(self, param) } |
476ff2be | 76 | fn visit_generics(&mut self, g: &'ast Generics) { walk_generics(self, g) } |
8bb4bdeb XL |
77 | fn visit_where_predicate(&mut self, p: &'ast WherePredicate) { |
78 | walk_where_predicate(self, p) | |
79 | } | |
476ff2be SL |
80 | fn visit_fn(&mut self, fk: FnKind<'ast>, fd: &'ast FnDecl, s: Span, _: NodeId) { |
81 | walk_fn(self, fk, fd, s) | |
82 | } | |
83 | fn visit_trait_item(&mut self, ti: &'ast TraitItem) { walk_trait_item(self, ti) } | |
84 | fn visit_impl_item(&mut self, ii: &'ast ImplItem) { walk_impl_item(self, ii) } | |
85 | fn visit_trait_ref(&mut self, t: &'ast TraitRef) { walk_trait_ref(self, t) } | |
86 | fn visit_ty_param_bound(&mut self, bounds: &'ast TyParamBound) { | |
1a4d82fc JJ |
87 | walk_ty_param_bound(self, bounds) |
88 | } | |
476ff2be | 89 | fn visit_poly_trait_ref(&mut self, t: &'ast PolyTraitRef, m: &'ast TraitBoundModifier) { |
1a4d82fc JJ |
90 | walk_poly_trait_ref(self, t, m) |
91 | } | |
476ff2be SL |
92 | fn visit_variant_data(&mut self, s: &'ast VariantData, _: Ident, |
93 | _: &'ast Generics, _: NodeId, _: Span) { | |
1a4d82fc JJ |
94 | walk_struct_def(self, s) |
95 | } | |
476ff2be SL |
96 | fn visit_struct_field(&mut self, s: &'ast StructField) { walk_struct_field(self, s) } |
97 | fn visit_enum_def(&mut self, enum_definition: &'ast EnumDef, | |
98 | generics: &'ast Generics, item_id: NodeId, _: Span) { | |
b039eaaf | 99 | walk_enum_def(self, enum_definition, generics, item_id) |
c1a9b12d | 100 | } |
476ff2be | 101 | fn visit_variant(&mut self, v: &'ast Variant, g: &'ast Generics, item_id: NodeId) { |
b039eaaf | 102 | walk_variant(self, v, g, item_id) |
1a4d82fc | 103 | } |
2c00a5a8 XL |
104 | fn visit_label(&mut self, label: &'ast Label) { |
105 | walk_label(self, label) | |
106 | } | |
476ff2be | 107 | fn visit_lifetime(&mut self, lifetime: &'ast Lifetime) { |
b039eaaf | 108 | walk_lifetime(self, lifetime) |
1a4d82fc | 109 | } |
476ff2be | 110 | fn visit_mac(&mut self, _mac: &'ast Mac) { |
1a4d82fc JJ |
111 | panic!("visit_mac disabled by default"); |
112 | // NB: see note about macros above. | |
113 | // if you really want a visitor that | |
114 | // works on macros, use this | |
115 | // definition in your trait impl: | |
116 | // visit::walk_mac(self, _mac) | |
117 | } | |
7cac9316 XL |
118 | fn visit_mac_def(&mut self, _mac: &'ast MacroDef, _id: NodeId) { |
119 | // Nothing to do | |
120 | } | |
476ff2be | 121 | fn visit_path(&mut self, path: &'ast Path, _id: NodeId) { |
1a4d82fc JJ |
122 | walk_path(self, path) |
123 | } | |
ff7c6d11 XL |
124 | fn visit_use_tree(&mut self, use_tree: &'ast UseTree, id: NodeId, _nested: bool) { |
125 | walk_use_tree(self, use_tree, id) | |
b039eaaf | 126 | } |
476ff2be | 127 | fn visit_path_segment(&mut self, path_span: Span, path_segment: &'ast PathSegment) { |
1a4d82fc JJ |
128 | walk_path_segment(self, path_span, path_segment) |
129 | } | |
476ff2be | 130 | fn visit_path_parameters(&mut self, path_span: Span, path_parameters: &'ast PathParameters) { |
1a4d82fc JJ |
131 | walk_path_parameters(self, path_span, path_parameters) |
132 | } | |
476ff2be | 133 | fn visit_assoc_type_binding(&mut self, type_binding: &'ast TypeBinding) { |
1a4d82fc JJ |
134 | walk_assoc_type_binding(self, type_binding) |
135 | } | |
abe05a73 XL |
136 | fn visit_attribute(&mut self, attr: &'ast Attribute) { |
137 | walk_attribute(self, attr) | |
138 | } | |
139 | fn visit_tt(&mut self, tt: TokenTree) { | |
140 | walk_tt(self, tt) | |
141 | } | |
142 | fn visit_tts(&mut self, tts: TokenStream) { | |
143 | walk_tts(self, tts) | |
144 | } | |
145 | fn visit_token(&mut self, _t: Token) {} | |
146 | // FIXME: add `visit_interpolated` and `walk_interpolated` | |
476ff2be | 147 | fn visit_vis(&mut self, vis: &'ast Visibility) { |
54a0048b SL |
148 | walk_vis(self, vis) |
149 | } | |
476ff2be | 150 | fn visit_fn_ret_ty(&mut self, ret_ty: &'ast FunctionRetTy) { |
5bcae85e SL |
151 | walk_fn_ret_ty(self, ret_ty) |
152 | } | |
223e47cc LB |
153 | } |
154 | ||
b039eaaf SL |
155 | #[macro_export] |
156 | macro_rules! walk_list { | |
157 | ($visitor: expr, $method: ident, $list: expr) => { | |
158 | for elem in $list { | |
159 | $visitor.$method(elem) | |
160 | } | |
161 | }; | |
162 | ($visitor: expr, $method: ident, $list: expr, $($extra_args: expr),*) => { | |
163 | for elem in $list { | |
164 | $visitor.$method(elem, $($extra_args,)*) | |
165 | } | |
1a4d82fc JJ |
166 | } |
167 | } | |
168 | ||
476ff2be | 169 | pub fn walk_ident<'a, V: Visitor<'a>>(visitor: &mut V, span: Span, ident: Ident) { |
b039eaaf SL |
170 | visitor.visit_name(span, ident.name); |
171 | } | |
172 | ||
476ff2be | 173 | pub fn walk_crate<'a, V: Visitor<'a>>(visitor: &mut V, krate: &'a Crate) { |
7cac9316 | 174 | visitor.visit_mod(&krate.module, krate.span, &krate.attrs, CRATE_NODE_ID); |
b039eaaf | 175 | walk_list!(visitor, visit_attribute, &krate.attrs); |
1a4d82fc JJ |
176 | } |
177 | ||
476ff2be | 178 | pub fn walk_mod<'a, V: Visitor<'a>>(visitor: &mut V, module: &'a Mod) { |
b039eaaf | 179 | walk_list!(visitor, visit_item, &module.items); |
1a4d82fc JJ |
180 | } |
181 | ||
476ff2be | 182 | pub fn walk_local<'a, V: Visitor<'a>>(visitor: &mut V, local: &'a Local) { |
3157f602 XL |
183 | for attr in local.attrs.iter() { |
184 | visitor.visit_attribute(attr); | |
185 | } | |
b039eaaf SL |
186 | visitor.visit_pat(&local.pat); |
187 | walk_list!(visitor, visit_ty, &local.ty); | |
188 | walk_list!(visitor, visit_expr, &local.init); | |
189 | } | |
190 | ||
2c00a5a8 XL |
191 | pub fn walk_label<'a, V: Visitor<'a>>(visitor: &mut V, label: &'a Label) { |
192 | visitor.visit_ident(label.span, label.ident); | |
193 | } | |
194 | ||
476ff2be | 195 | pub fn walk_lifetime<'a, V: Visitor<'a>>(visitor: &mut V, lifetime: &'a Lifetime) { |
7cac9316 | 196 | visitor.visit_ident(lifetime.span, lifetime.ident); |
b039eaaf SL |
197 | } |
198 | ||
476ff2be SL |
199 | pub fn walk_poly_trait_ref<'a, V>(visitor: &mut V, |
200 | trait_ref: &'a PolyTraitRef, | |
201 | _: &TraitBoundModifier) | |
202 | where V: Visitor<'a>, | |
1a4d82fc | 203 | { |
ff7c6d11 | 204 | walk_list!(visitor, visit_generic_param, &trait_ref.bound_generic_params); |
1a4d82fc JJ |
205 | visitor.visit_trait_ref(&trait_ref.trait_ref); |
206 | } | |
207 | ||
476ff2be | 208 | pub fn walk_trait_ref<'a, V: Visitor<'a>>(visitor: &mut V, trait_ref: &'a TraitRef) { |
1a4d82fc JJ |
209 | visitor.visit_path(&trait_ref.path, trait_ref.ref_id) |
210 | } | |
211 | ||
476ff2be | 212 | pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { |
a7813a04 | 213 | visitor.visit_vis(&item.vis); |
1a4d82fc JJ |
214 | visitor.visit_ident(item.span, item.ident); |
215 | match item.node { | |
7453a54e | 216 | ItemKind::ExternCrate(opt_name) => { |
2c00a5a8 XL |
217 | if let Some(name) = opt_name { |
218 | visitor.visit_name(item.span, name); | |
219 | } | |
b039eaaf | 220 | } |
ff7c6d11 XL |
221 | ItemKind::Use(ref use_tree) => { |
222 | visitor.visit_use_tree(use_tree, item.id, false) | |
85aaf69f | 223 | } |
7453a54e SL |
224 | ItemKind::Static(ref typ, _, ref expr) | |
225 | ItemKind::Const(ref typ, ref expr) => { | |
b039eaaf SL |
226 | visitor.visit_ty(typ); |
227 | visitor.visit_expr(expr); | |
1a4d82fc | 228 | } |
7453a54e | 229 | ItemKind::Fn(ref declaration, unsafety, constness, abi, ref generics, ref body) => { |
abe05a73 XL |
230 | visitor.visit_generics(generics); |
231 | visitor.visit_fn(FnKind::ItemFn(item.ident, unsafety, | |
476ff2be | 232 | constness, abi, &item.vis, body), |
b039eaaf | 233 | declaration, |
1a4d82fc JJ |
234 | item.span, |
235 | item.id) | |
236 | } | |
7453a54e | 237 | ItemKind::Mod(ref module) => { |
7cac9316 | 238 | visitor.visit_mod(module, item.span, &item.attrs, item.id) |
1a4d82fc | 239 | } |
7453a54e | 240 | ItemKind::ForeignMod(ref foreign_module) => { |
b039eaaf | 241 | walk_list!(visitor, visit_foreign_item, &foreign_module.items); |
223e47cc | 242 | } |
cc61c64b | 243 | ItemKind::GlobalAsm(ref ga) => visitor.visit_global_asm(ga), |
7453a54e | 244 | ItemKind::Ty(ref typ, ref type_parameters) => { |
b039eaaf | 245 | visitor.visit_ty(typ); |
1a4d82fc JJ |
246 | visitor.visit_generics(type_parameters) |
247 | } | |
7453a54e | 248 | ItemKind::Enum(ref enum_definition, ref type_parameters) => { |
1a4d82fc | 249 | visitor.visit_generics(type_parameters); |
b039eaaf | 250 | visitor.visit_enum_def(enum_definition, type_parameters, item.id, item.span) |
1a4d82fc | 251 | } |
7cac9316 | 252 | ItemKind::Impl(_, _, _, |
1a4d82fc | 253 | ref type_parameters, |
b039eaaf | 254 | ref opt_trait_reference, |
1a4d82fc JJ |
255 | ref typ, |
256 | ref impl_items) => { | |
257 | visitor.visit_generics(type_parameters); | |
b039eaaf SL |
258 | walk_list!(visitor, visit_trait_ref, opt_trait_reference); |
259 | visitor.visit_ty(typ); | |
260 | walk_list!(visitor, visit_impl_item, impl_items); | |
970d7e83 | 261 | } |
9e0c209e SL |
262 | ItemKind::Struct(ref struct_definition, ref generics) | |
263 | ItemKind::Union(ref struct_definition, ref generics) => { | |
1a4d82fc | 264 | visitor.visit_generics(generics); |
b039eaaf SL |
265 | visitor.visit_variant_data(struct_definition, item.ident, |
266 | generics, item.id, item.span); | |
1a4d82fc | 267 | } |
abe05a73 | 268 | ItemKind::Trait(.., ref generics, ref bounds, ref methods) => { |
1a4d82fc | 269 | visitor.visit_generics(generics); |
b039eaaf SL |
270 | walk_list!(visitor, visit_ty_param_bound, bounds); |
271 | walk_list!(visitor, visit_trait_item, methods); | |
1a4d82fc | 272 | } |
ff7c6d11 XL |
273 | ItemKind::TraitAlias(ref generics, ref bounds) => { |
274 | visitor.visit_generics(generics); | |
275 | walk_list!(visitor, visit_ty_param_bound, bounds); | |
276 | } | |
7453a54e | 277 | ItemKind::Mac(ref mac) => visitor.visit_mac(mac), |
7cac9316 | 278 | ItemKind::MacroDef(ref ts) => visitor.visit_mac_def(ts, item.id), |
1a4d82fc | 279 | } |
b039eaaf | 280 | walk_list!(visitor, visit_attribute, &item.attrs); |
223e47cc LB |
281 | } |
282 | ||
476ff2be SL |
283 | pub fn walk_enum_def<'a, V: Visitor<'a>>(visitor: &mut V, |
284 | enum_definition: &'a EnumDef, | |
285 | generics: &'a Generics, | |
3157f602 | 286 | item_id: NodeId) { |
b039eaaf | 287 | walk_list!(visitor, visit_variant, &enum_definition.variants, generics, item_id); |
1a4d82fc | 288 | } |
223e47cc | 289 | |
476ff2be SL |
290 | pub fn walk_variant<'a, V>(visitor: &mut V, |
291 | variant: &'a Variant, | |
292 | generics: &'a Generics, | |
293 | item_id: NodeId) | |
294 | where V: Visitor<'a>, | |
3157f602 | 295 | { |
1a4d82fc | 296 | visitor.visit_ident(variant.span, variant.node.name); |
b039eaaf SL |
297 | visitor.visit_variant_data(&variant.node.data, variant.node.name, |
298 | generics, item_id, variant.span); | |
299 | walk_list!(visitor, visit_expr, &variant.node.disr_expr); | |
300 | walk_list!(visitor, visit_attribute, &variant.node.attrs); | |
1a4d82fc JJ |
301 | } |
302 | ||
476ff2be | 303 | pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) { |
1a4d82fc | 304 | match typ.node { |
c30ab7b3 | 305 | TyKind::Slice(ref ty) | TyKind::Paren(ref ty) => { |
b039eaaf | 306 | visitor.visit_ty(ty) |
1a4d82fc | 307 | } |
7453a54e | 308 | TyKind::Ptr(ref mutable_type) => { |
b039eaaf | 309 | visitor.visit_ty(&mutable_type.ty) |
1a4d82fc | 310 | } |
7453a54e | 311 | TyKind::Rptr(ref opt_lifetime, ref mutable_type) => { |
b039eaaf SL |
312 | walk_list!(visitor, visit_lifetime, opt_lifetime); |
313 | visitor.visit_ty(&mutable_type.ty) | |
1a4d82fc | 314 | } |
5bcae85e | 315 | TyKind::Never => {}, |
7453a54e | 316 | TyKind::Tup(ref tuple_element_types) => { |
b039eaaf | 317 | walk_list!(visitor, visit_ty, tuple_element_types); |
1a4d82fc | 318 | } |
7453a54e | 319 | TyKind::BareFn(ref function_declaration) => { |
b039eaaf | 320 | walk_fn_decl(visitor, &function_declaration.decl); |
ff7c6d11 | 321 | walk_list!(visitor, visit_generic_param, &function_declaration.generic_params); |
1a4d82fc | 322 | } |
7453a54e | 323 | TyKind::Path(ref maybe_qself, ref path) => { |
c34b1796 AL |
324 | if let Some(ref qself) = *maybe_qself { |
325 | visitor.visit_ty(&qself.ty); | |
326 | } | |
327 | visitor.visit_path(path, typ.id); | |
1a4d82fc | 328 | } |
c30ab7b3 | 329 | TyKind::Array(ref ty, ref expression) => { |
b039eaaf SL |
330 | visitor.visit_ty(ty); |
331 | visitor.visit_expr(expression) | |
1a4d82fc | 332 | } |
abe05a73 | 333 | TyKind::TraitObject(ref bounds, ..) | |
5bcae85e SL |
334 | TyKind::ImplTrait(ref bounds) => { |
335 | walk_list!(visitor, visit_ty_param_bound, bounds); | |
336 | } | |
7453a54e | 337 | TyKind::Typeof(ref expression) => { |
b039eaaf | 338 | visitor.visit_expr(expression) |
1a4d82fc | 339 | } |
cc61c64b | 340 | TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err => {} |
7453a54e | 341 | TyKind::Mac(ref mac) => { |
e9174d1e SL |
342 | visitor.visit_mac(mac) |
343 | } | |
1a4d82fc JJ |
344 | } |
345 | } | |
346 | ||
476ff2be | 347 | pub fn walk_path<'a, V: Visitor<'a>>(visitor: &mut V, path: &'a Path) { |
85aaf69f | 348 | for segment in &path.segments { |
1a4d82fc JJ |
349 | visitor.visit_path_segment(path.span, segment); |
350 | } | |
351 | } | |
352 | ||
ff7c6d11 XL |
353 | pub fn walk_use_tree<'a, V: Visitor<'a>>( |
354 | visitor: &mut V, use_tree: &'a UseTree, id: NodeId, | |
355 | ) { | |
356 | visitor.visit_path(&use_tree.prefix, id); | |
357 | ||
358 | match use_tree.kind { | |
359 | UseTreeKind::Simple(ident) => { | |
360 | visitor.visit_ident(use_tree.span, ident); | |
361 | } | |
362 | UseTreeKind::Glob => {}, | |
363 | UseTreeKind::Nested(ref use_trees) => { | |
364 | for &(ref nested_tree, nested_id) in use_trees { | |
365 | visitor.visit_use_tree(nested_tree, nested_id, true); | |
366 | } | |
367 | } | |
368 | } | |
b039eaaf SL |
369 | } |
370 | ||
476ff2be SL |
371 | pub fn walk_path_segment<'a, V: Visitor<'a>>(visitor: &mut V, |
372 | path_span: Span, | |
373 | segment: &'a PathSegment) { | |
1a4d82fc | 374 | visitor.visit_ident(path_span, segment.identifier); |
32a655c1 SL |
375 | if let Some(ref parameters) = segment.parameters { |
376 | visitor.visit_path_parameters(path_span, parameters); | |
377 | } | |
1a4d82fc JJ |
378 | } |
379 | ||
476ff2be SL |
380 | pub fn walk_path_parameters<'a, V>(visitor: &mut V, |
381 | _path_span: Span, | |
382 | path_parameters: &'a PathParameters) | |
383 | where V: Visitor<'a>, | |
3157f602 | 384 | { |
1a4d82fc | 385 | match *path_parameters { |
9cc50fc6 | 386 | PathParameters::AngleBracketed(ref data) => { |
b039eaaf SL |
387 | walk_list!(visitor, visit_ty, &data.types); |
388 | walk_list!(visitor, visit_lifetime, &data.lifetimes); | |
389 | walk_list!(visitor, visit_assoc_type_binding, &data.bindings); | |
1a4d82fc | 390 | } |
9cc50fc6 | 391 | PathParameters::Parenthesized(ref data) => { |
b039eaaf SL |
392 | walk_list!(visitor, visit_ty, &data.inputs); |
393 | walk_list!(visitor, visit_ty, &data.output); | |
1a4d82fc JJ |
394 | } |
395 | } | |
396 | } | |
397 | ||
476ff2be SL |
398 | pub fn walk_assoc_type_binding<'a, V: Visitor<'a>>(visitor: &mut V, |
399 | type_binding: &'a TypeBinding) { | |
1a4d82fc | 400 | visitor.visit_ident(type_binding.span, type_binding.ident); |
b039eaaf | 401 | visitor.visit_ty(&type_binding.ty); |
1a4d82fc JJ |
402 | } |
403 | ||
476ff2be | 404 | pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) { |
1a4d82fc | 405 | match pattern.node { |
3157f602 | 406 | PatKind::TupleStruct(ref path, ref children, _) => { |
7453a54e | 407 | visitor.visit_path(path, pattern.id); |
3157f602 | 408 | walk_list!(visitor, visit_pat, children); |
7453a54e | 409 | } |
3157f602 XL |
410 | PatKind::Path(ref opt_qself, ref path) => { |
411 | if let Some(ref qself) = *opt_qself { | |
412 | visitor.visit_ty(&qself.ty); | |
413 | } | |
d9579d0f AL |
414 | visitor.visit_path(path, pattern.id) |
415 | } | |
7453a54e | 416 | PatKind::Struct(ref path, ref fields, _) => { |
1a4d82fc | 417 | visitor.visit_path(path, pattern.id); |
85aaf69f | 418 | for field in fields { |
32a655c1 | 419 | walk_list!(visitor, visit_attribute, field.node.attrs.iter()); |
b039eaaf SL |
420 | visitor.visit_ident(field.span, field.node.ident); |
421 | visitor.visit_pat(&field.node.pat) | |
223e47cc LB |
422 | } |
423 | } | |
3157f602 | 424 | PatKind::Tuple(ref tuple_elements, _) => { |
b039eaaf | 425 | walk_list!(visitor, visit_pat, tuple_elements); |
1a4d82fc | 426 | } |
7453a54e SL |
427 | PatKind::Box(ref subpattern) | |
428 | PatKind::Ref(ref subpattern, _) => { | |
b039eaaf | 429 | visitor.visit_pat(subpattern) |
1a4d82fc | 430 | } |
7453a54e | 431 | PatKind::Ident(_, ref pth1, ref optional_subpattern) => { |
1a4d82fc | 432 | visitor.visit_ident(pth1.span, pth1.node); |
b039eaaf | 433 | walk_list!(visitor, visit_pat, optional_subpattern); |
223e47cc | 434 | } |
7453a54e | 435 | PatKind::Lit(ref expression) => visitor.visit_expr(expression), |
32a655c1 | 436 | PatKind::Range(ref lower_bound, ref upper_bound, _) => { |
b039eaaf | 437 | visitor.visit_expr(lower_bound); |
32a655c1 | 438 | visitor.visit_expr(upper_bound); |
223e47cc | 439 | } |
7453a54e | 440 | PatKind::Wild => (), |
c30ab7b3 | 441 | PatKind::Slice(ref prepatterns, ref slice_pattern, ref postpatterns) => { |
b039eaaf SL |
442 | walk_list!(visitor, visit_pat, prepatterns); |
443 | walk_list!(visitor, visit_pat, slice_pattern); | |
444 | walk_list!(visitor, visit_pat, postpatterns); | |
223e47cc | 445 | } |
7453a54e | 446 | PatKind::Mac(ref mac) => visitor.visit_mac(mac), |
1a4d82fc JJ |
447 | } |
448 | } | |
449 | ||
476ff2be | 450 | pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, foreign_item: &'a ForeignItem) { |
a7813a04 | 451 | visitor.visit_vis(&foreign_item.vis); |
1a4d82fc JJ |
452 | visitor.visit_ident(foreign_item.span, foreign_item.ident); |
453 | ||
454 | match foreign_item.node { | |
7453a54e | 455 | ForeignItemKind::Fn(ref function_declaration, ref generics) => { |
b039eaaf | 456 | walk_fn_decl(visitor, function_declaration); |
1a4d82fc JJ |
457 | visitor.visit_generics(generics) |
458 | } | |
7453a54e | 459 | ForeignItemKind::Static(ref typ, _) => visitor.visit_ty(typ), |
abe05a73 | 460 | ForeignItemKind::Ty => (), |
223e47cc | 461 | } |
223e47cc | 462 | |
b039eaaf | 463 | walk_list!(visitor, visit_attribute, &foreign_item.attrs); |
1a4d82fc JJ |
464 | } |
465 | ||
cc61c64b XL |
466 | pub fn walk_global_asm<'a, V: Visitor<'a>>(_: &mut V, _: &'a GlobalAsm) { |
467 | // Empty! | |
468 | } | |
469 | ||
476ff2be | 470 | pub fn walk_ty_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a TyParamBound) { |
1a4d82fc JJ |
471 | match *bound { |
472 | TraitTyParamBound(ref typ, ref modifier) => { | |
473 | visitor.visit_poly_trait_ref(typ, modifier); | |
223e47cc | 474 | } |
1a4d82fc | 475 | RegionTyParamBound(ref lifetime) => { |
b039eaaf | 476 | visitor.visit_lifetime(lifetime); |
223e47cc LB |
477 | } |
478 | } | |
479 | } | |
480 | ||
ff7c6d11 XL |
481 | pub fn walk_generic_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a GenericParam) { |
482 | match *param { | |
483 | GenericParam::Lifetime(ref l) => { | |
484 | visitor.visit_lifetime(&l.lifetime); | |
485 | walk_list!(visitor, visit_lifetime, &l.bounds); | |
486 | walk_list!(visitor, visit_attribute, &*l.attrs); | |
487 | } | |
488 | GenericParam::Type(ref t) => { | |
489 | visitor.visit_ident(t.span, t.ident); | |
490 | walk_list!(visitor, visit_ty_param_bound, &t.bounds); | |
491 | walk_list!(visitor, visit_ty, &t.default); | |
492 | walk_list!(visitor, visit_attribute, &*t.attrs); | |
493 | } | |
1a4d82fc | 494 | } |
ff7c6d11 XL |
495 | } |
496 | ||
497 | pub fn walk_generics<'a, V: Visitor<'a>>(visitor: &mut V, generics: &'a Generics) { | |
498 | walk_list!(visitor, visit_generic_param, &generics.params); | |
8bb4bdeb XL |
499 | walk_list!(visitor, visit_where_predicate, &generics.where_clause.predicates); |
500 | } | |
501 | ||
502 | pub fn walk_where_predicate<'a, V: Visitor<'a>>(visitor: &mut V, predicate: &'a WherePredicate) { | |
503 | match *predicate { | |
504 | WherePredicate::BoundPredicate(WhereBoundPredicate{ref bounded_ty, | |
505 | ref bounds, | |
ff7c6d11 | 506 | ref bound_generic_params, |
8bb4bdeb XL |
507 | ..}) => { |
508 | visitor.visit_ty(bounded_ty); | |
509 | walk_list!(visitor, visit_ty_param_bound, bounds); | |
ff7c6d11 | 510 | walk_list!(visitor, visit_generic_param, bound_generic_params); |
8bb4bdeb XL |
511 | } |
512 | WherePredicate::RegionPredicate(WhereRegionPredicate{ref lifetime, | |
513 | ref bounds, | |
514 | ..}) => { | |
515 | visitor.visit_lifetime(lifetime); | |
516 | walk_list!(visitor, visit_lifetime, bounds); | |
517 | } | |
518 | WherePredicate::EqPredicate(WhereEqPredicate{ref lhs_ty, | |
519 | ref rhs_ty, | |
520 | ..}) => { | |
521 | visitor.visit_ty(lhs_ty); | |
522 | visitor.visit_ty(rhs_ty); | |
223e47cc LB |
523 | } |
524 | } | |
525 | } | |
526 | ||
476ff2be | 527 | pub fn walk_fn_ret_ty<'a, V: Visitor<'a>>(visitor: &mut V, ret_ty: &'a FunctionRetTy) { |
7453a54e | 528 | if let FunctionRetTy::Ty(ref output_ty) = *ret_ty { |
b039eaaf | 529 | visitor.visit_ty(output_ty) |
223e47cc LB |
530 | } |
531 | } | |
532 | ||
476ff2be | 533 | pub fn walk_fn_decl<'a, V: Visitor<'a>>(visitor: &mut V, function_declaration: &'a FnDecl) { |
85aaf69f | 534 | for argument in &function_declaration.inputs { |
b039eaaf SL |
535 | visitor.visit_pat(&argument.pat); |
536 | visitor.visit_ty(&argument.ty) | |
223e47cc | 537 | } |
5bcae85e | 538 | visitor.visit_fn_ret_ty(&function_declaration.output) |
223e47cc LB |
539 | } |
540 | ||
476ff2be SL |
541 | pub fn walk_fn<'a, V>(visitor: &mut V, kind: FnKind<'a>, declaration: &'a FnDecl, _span: Span) |
542 | where V: Visitor<'a>, | |
543 | { | |
544 | match kind { | |
abe05a73 | 545 | FnKind::ItemFn(_, _, _, _, _, body) => { |
476ff2be SL |
546 | walk_fn_decl(visitor, declaration); |
547 | visitor.visit_block(body); | |
1a4d82fc | 548 | } |
abe05a73 | 549 | FnKind::Method(_, _, _, body) => { |
476ff2be SL |
550 | walk_fn_decl(visitor, declaration); |
551 | visitor.visit_block(body); | |
552 | } | |
553 | FnKind::Closure(body) => { | |
554 | walk_fn_decl(visitor, declaration); | |
555 | visitor.visit_expr(body); | |
1a4d82fc | 556 | } |
1a4d82fc | 557 | } |
b039eaaf | 558 | } |
1a4d82fc | 559 | |
476ff2be | 560 | pub fn walk_trait_item<'a, V: Visitor<'a>>(visitor: &mut V, trait_item: &'a TraitItem) { |
c34b1796 | 561 | visitor.visit_ident(trait_item.span, trait_item.ident); |
b039eaaf | 562 | walk_list!(visitor, visit_attribute, &trait_item.attrs); |
abe05a73 | 563 | visitor.visit_generics(&trait_item.generics); |
c34b1796 | 564 | match trait_item.node { |
7453a54e | 565 | TraitItemKind::Const(ref ty, ref default) => { |
d9579d0f | 566 | visitor.visit_ty(ty); |
b039eaaf | 567 | walk_list!(visitor, visit_expr, default); |
d9579d0f | 568 | } |
7453a54e | 569 | TraitItemKind::Method(ref sig, None) => { |
c34b1796 AL |
570 | walk_fn_decl(visitor, &sig.decl); |
571 | } | |
7453a54e | 572 | TraitItemKind::Method(ref sig, Some(ref body)) => { |
476ff2be SL |
573 | visitor.visit_fn(FnKind::Method(trait_item.ident, sig, None, body), |
574 | &sig.decl, trait_item.span, trait_item.id); | |
c34b1796 | 575 | } |
7453a54e | 576 | TraitItemKind::Type(ref bounds, ref default) => { |
b039eaaf SL |
577 | walk_list!(visitor, visit_ty_param_bound, bounds); |
578 | walk_list!(visitor, visit_ty, default); | |
c34b1796 | 579 | } |
3157f602 XL |
580 | TraitItemKind::Macro(ref mac) => { |
581 | visitor.visit_mac(mac); | |
582 | } | |
c34b1796 | 583 | } |
223e47cc LB |
584 | } |
585 | ||
476ff2be | 586 | pub fn walk_impl_item<'a, V: Visitor<'a>>(visitor: &mut V, impl_item: &'a ImplItem) { |
a7813a04 | 587 | visitor.visit_vis(&impl_item.vis); |
c34b1796 | 588 | visitor.visit_ident(impl_item.span, impl_item.ident); |
b039eaaf | 589 | walk_list!(visitor, visit_attribute, &impl_item.attrs); |
abe05a73 | 590 | visitor.visit_generics(&impl_item.generics); |
c34b1796 | 591 | match impl_item.node { |
92a42be0 | 592 | ImplItemKind::Const(ref ty, ref expr) => { |
d9579d0f AL |
593 | visitor.visit_ty(ty); |
594 | visitor.visit_expr(expr); | |
595 | } | |
92a42be0 | 596 | ImplItemKind::Method(ref sig, ref body) => { |
476ff2be SL |
597 | visitor.visit_fn(FnKind::Method(impl_item.ident, sig, Some(&impl_item.vis), body), |
598 | &sig.decl, impl_item.span, impl_item.id); | |
c34b1796 | 599 | } |
92a42be0 | 600 | ImplItemKind::Type(ref ty) => { |
c34b1796 AL |
601 | visitor.visit_ty(ty); |
602 | } | |
92a42be0 | 603 | ImplItemKind::Macro(ref mac) => { |
c34b1796 | 604 | visitor.visit_mac(mac); |
1a4d82fc | 605 | } |
223e47cc LB |
606 | } |
607 | } | |
608 | ||
476ff2be | 609 | pub fn walk_struct_def<'a, V: Visitor<'a>>(visitor: &mut V, struct_definition: &'a VariantData) { |
b039eaaf | 610 | walk_list!(visitor, visit_struct_field, struct_definition.fields()); |
223e47cc LB |
611 | } |
612 | ||
476ff2be | 613 | pub fn walk_struct_field<'a, V: Visitor<'a>>(visitor: &mut V, struct_field: &'a StructField) { |
a7813a04 | 614 | visitor.visit_vis(&struct_field.vis); |
2c00a5a8 XL |
615 | if let Some(ident) = struct_field.ident { |
616 | visitor.visit_ident(struct_field.span, ident); | |
617 | } | |
54a0048b SL |
618 | visitor.visit_ty(&struct_field.ty); |
619 | walk_list!(visitor, visit_attribute, &struct_field.attrs); | |
223e47cc LB |
620 | } |
621 | ||
476ff2be | 622 | pub fn walk_block<'a, V: Visitor<'a>>(visitor: &mut V, block: &'a Block) { |
b039eaaf | 623 | walk_list!(visitor, visit_stmt, &block.stmts); |
223e47cc LB |
624 | } |
625 | ||
476ff2be | 626 | pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) { |
1a4d82fc | 627 | match statement.node { |
3157f602 XL |
628 | StmtKind::Local(ref local) => visitor.visit_local(local), |
629 | StmtKind::Item(ref item) => visitor.visit_item(item), | |
630 | StmtKind::Expr(ref expression) | StmtKind::Semi(ref expression) => { | |
b039eaaf | 631 | visitor.visit_expr(expression) |
1a4d82fc | 632 | } |
3157f602 XL |
633 | StmtKind::Mac(ref mac) => { |
634 | let (ref mac, _, ref attrs) = **mac; | |
92a42be0 | 635 | visitor.visit_mac(mac); |
3157f602 | 636 | for attr in attrs.iter() { |
92a42be0 SL |
637 | visitor.visit_attribute(attr); |
638 | } | |
639 | } | |
223e47cc LB |
640 | } |
641 | } | |
642 | ||
476ff2be | 643 | pub fn walk_mac<'a, V: Visitor<'a>>(_: &mut V, _: &Mac) { |
1a4d82fc | 644 | // Empty! |
223e47cc LB |
645 | } |
646 | ||
476ff2be | 647 | pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) { |
3157f602 XL |
648 | for attr in expression.attrs.iter() { |
649 | visitor.visit_attribute(attr); | |
650 | } | |
1a4d82fc | 651 | match expression.node { |
7453a54e | 652 | ExprKind::Box(ref subexpression) => { |
b039eaaf SL |
653 | visitor.visit_expr(subexpression) |
654 | } | |
7453a54e | 655 | ExprKind::InPlace(ref place, ref subexpression) => { |
b039eaaf SL |
656 | visitor.visit_expr(place); |
657 | visitor.visit_expr(subexpression) | |
223e47cc | 658 | } |
32a655c1 | 659 | ExprKind::Array(ref subexpressions) => { |
b039eaaf | 660 | walk_list!(visitor, visit_expr, subexpressions); |
1a4d82fc | 661 | } |
7453a54e | 662 | ExprKind::Repeat(ref element, ref count) => { |
b039eaaf SL |
663 | visitor.visit_expr(element); |
664 | visitor.visit_expr(count) | |
1a4d82fc | 665 | } |
7453a54e | 666 | ExprKind::Struct(ref path, ref fields, ref optional_base) => { |
1a4d82fc | 667 | visitor.visit_path(path, expression.id); |
85aaf69f | 668 | for field in fields { |
32a655c1 | 669 | walk_list!(visitor, visit_attribute, field.attrs.iter()); |
b039eaaf SL |
670 | visitor.visit_ident(field.ident.span, field.ident.node); |
671 | visitor.visit_expr(&field.expr) | |
970d7e83 | 672 | } |
b039eaaf | 673 | walk_list!(visitor, visit_expr, optional_base); |
223e47cc | 674 | } |
7453a54e | 675 | ExprKind::Tup(ref subexpressions) => { |
b039eaaf | 676 | walk_list!(visitor, visit_expr, subexpressions); |
223e47cc | 677 | } |
7453a54e | 678 | ExprKind::Call(ref callee_expression, ref arguments) => { |
9e0c209e | 679 | visitor.visit_expr(callee_expression); |
b039eaaf | 680 | walk_list!(visitor, visit_expr, arguments); |
1a4d82fc | 681 | } |
041b39d2 XL |
682 | ExprKind::MethodCall(ref segment, ref arguments) => { |
683 | visitor.visit_path_segment(expression.span, segment); | |
9e0c209e | 684 | walk_list!(visitor, visit_expr, arguments); |
223e47cc | 685 | } |
7453a54e | 686 | ExprKind::Binary(_, ref left_expression, ref right_expression) => { |
b039eaaf SL |
687 | visitor.visit_expr(left_expression); |
688 | visitor.visit_expr(right_expression) | |
1a4d82fc | 689 | } |
7453a54e | 690 | ExprKind::AddrOf(_, ref subexpression) | ExprKind::Unary(_, ref subexpression) => { |
b039eaaf | 691 | visitor.visit_expr(subexpression) |
1a4d82fc | 692 | } |
7453a54e SL |
693 | ExprKind::Lit(_) => {} |
694 | ExprKind::Cast(ref subexpression, ref typ) | ExprKind::Type(ref subexpression, ref typ) => { | |
b039eaaf SL |
695 | visitor.visit_expr(subexpression); |
696 | visitor.visit_ty(typ) | |
1a4d82fc | 697 | } |
7453a54e | 698 | ExprKind::If(ref head_expression, ref if_block, ref optional_else) => { |
b039eaaf SL |
699 | visitor.visit_expr(head_expression); |
700 | visitor.visit_block(if_block); | |
701 | walk_list!(visitor, visit_expr, optional_else); | |
1a4d82fc | 702 | } |
2c00a5a8 XL |
703 | ExprKind::While(ref subexpression, ref block, ref opt_label) => { |
704 | walk_list!(visitor, visit_label, opt_label); | |
b039eaaf SL |
705 | visitor.visit_expr(subexpression); |
706 | visitor.visit_block(block); | |
1a4d82fc | 707 | } |
7453a54e | 708 | ExprKind::IfLet(ref pattern, ref subexpression, ref if_block, ref optional_else) => { |
b039eaaf SL |
709 | visitor.visit_pat(pattern); |
710 | visitor.visit_expr(subexpression); | |
711 | visitor.visit_block(if_block); | |
712 | walk_list!(visitor, visit_expr, optional_else); | |
713 | } | |
2c00a5a8 XL |
714 | ExprKind::WhileLet(ref pattern, ref subexpression, ref block, ref opt_label) => { |
715 | walk_list!(visitor, visit_label, opt_label); | |
b039eaaf SL |
716 | visitor.visit_pat(pattern); |
717 | visitor.visit_expr(subexpression); | |
718 | visitor.visit_block(block); | |
b039eaaf | 719 | } |
2c00a5a8 XL |
720 | ExprKind::ForLoop(ref pattern, ref subexpression, ref block, ref opt_label) => { |
721 | walk_list!(visitor, visit_label, opt_label); | |
b039eaaf SL |
722 | visitor.visit_pat(pattern); |
723 | visitor.visit_expr(subexpression); | |
724 | visitor.visit_block(block); | |
b039eaaf | 725 | } |
2c00a5a8 XL |
726 | ExprKind::Loop(ref block, ref opt_label) => { |
727 | walk_list!(visitor, visit_label, opt_label); | |
b039eaaf | 728 | visitor.visit_block(block); |
b039eaaf | 729 | } |
7453a54e | 730 | ExprKind::Match(ref subexpression, ref arms) => { |
b039eaaf SL |
731 | visitor.visit_expr(subexpression); |
732 | walk_list!(visitor, visit_arm, arms); | |
223e47cc | 733 | } |
2c00a5a8 | 734 | ExprKind::Closure(_, _, ref function_declaration, ref body, _decl_span) => { |
476ff2be | 735 | visitor.visit_fn(FnKind::Closure(body), |
b039eaaf | 736 | function_declaration, |
1a4d82fc JJ |
737 | expression.span, |
738 | expression.id) | |
739 | } | |
7453a54e SL |
740 | ExprKind::Block(ref block) => visitor.visit_block(block), |
741 | ExprKind::Assign(ref left_hand_expression, ref right_hand_expression) => { | |
9e0c209e | 742 | visitor.visit_expr(left_hand_expression); |
b039eaaf | 743 | visitor.visit_expr(right_hand_expression); |
1a4d82fc | 744 | } |
7453a54e | 745 | ExprKind::AssignOp(_, ref left_expression, ref right_expression) => { |
9e0c209e | 746 | visitor.visit_expr(left_expression); |
b039eaaf | 747 | visitor.visit_expr(right_expression); |
223e47cc | 748 | } |
7453a54e | 749 | ExprKind::Field(ref subexpression, ref ident) => { |
b039eaaf SL |
750 | visitor.visit_expr(subexpression); |
751 | visitor.visit_ident(ident.span, ident.node); | |
223e47cc | 752 | } |
7453a54e | 753 | ExprKind::TupField(ref subexpression, _) => { |
b039eaaf | 754 | visitor.visit_expr(subexpression); |
223e47cc | 755 | } |
7453a54e | 756 | ExprKind::Index(ref main_expression, ref index_expression) => { |
b039eaaf SL |
757 | visitor.visit_expr(main_expression); |
758 | visitor.visit_expr(index_expression) | |
223e47cc | 759 | } |
54a0048b | 760 | ExprKind::Range(ref start, ref end, _) => { |
b039eaaf SL |
761 | walk_list!(visitor, visit_expr, start); |
762 | walk_list!(visitor, visit_expr, end); | |
223e47cc | 763 | } |
7453a54e | 764 | ExprKind::Path(ref maybe_qself, ref path) => { |
c34b1796 AL |
765 | if let Some(ref qself) = *maybe_qself { |
766 | visitor.visit_ty(&qself.ty); | |
767 | } | |
1a4d82fc | 768 | visitor.visit_path(path, expression.id) |
223e47cc | 769 | } |
2c00a5a8 XL |
770 | ExprKind::Break(ref opt_label, ref opt_expr) => { |
771 | walk_list!(visitor, visit_label, opt_label); | |
476ff2be SL |
772 | walk_list!(visitor, visit_expr, opt_expr); |
773 | } | |
2c00a5a8 XL |
774 | ExprKind::Continue(ref opt_label) => { |
775 | walk_list!(visitor, visit_label, opt_label); | |
b039eaaf | 776 | } |
7453a54e | 777 | ExprKind::Ret(ref optional_expression) => { |
b039eaaf | 778 | walk_list!(visitor, visit_expr, optional_expression); |
1a4d82fc | 779 | } |
7453a54e SL |
780 | ExprKind::Mac(ref mac) => visitor.visit_mac(mac), |
781 | ExprKind::Paren(ref subexpression) => { | |
b039eaaf | 782 | visitor.visit_expr(subexpression) |
1a4d82fc | 783 | } |
7453a54e | 784 | ExprKind::InlineAsm(ref ia) => { |
b039eaaf | 785 | for &(_, ref input) in &ia.inputs { |
7cac9316 | 786 | visitor.visit_expr(input) |
1a4d82fc | 787 | } |
9cc50fc6 SL |
788 | for output in &ia.outputs { |
789 | visitor.visit_expr(&output.expr) | |
1a4d82fc JJ |
790 | } |
791 | } | |
ea8adc8c XL |
792 | ExprKind::Yield(ref optional_expression) => { |
793 | walk_list!(visitor, visit_expr, optional_expression); | |
794 | } | |
54a0048b SL |
795 | ExprKind::Try(ref subexpression) => { |
796 | visitor.visit_expr(subexpression) | |
797 | } | |
cc61c64b XL |
798 | ExprKind::Catch(ref body) => { |
799 | visitor.visit_block(body) | |
800 | } | |
1a4d82fc JJ |
801 | } |
802 | ||
803 | visitor.visit_expr_post(expression) | |
804 | } | |
805 | ||
476ff2be | 806 | pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) { |
b039eaaf SL |
807 | walk_list!(visitor, visit_pat, &arm.pats); |
808 | walk_list!(visitor, visit_expr, &arm.guard); | |
809 | visitor.visit_expr(&arm.body); | |
810 | walk_list!(visitor, visit_attribute, &arm.attrs); | |
223e47cc | 811 | } |
54a0048b | 812 | |
476ff2be | 813 | pub fn walk_vis<'a, V: Visitor<'a>>(visitor: &mut V, vis: &'a Visibility) { |
a7813a04 XL |
814 | if let Visibility::Restricted { ref path, id } = *vis { |
815 | visitor.visit_path(path, id); | |
54a0048b SL |
816 | } |
817 | } | |
abe05a73 XL |
818 | |
819 | pub fn walk_attribute<'a, V: Visitor<'a>>(visitor: &mut V, attr: &'a Attribute) { | |
820 | visitor.visit_tts(attr.tokens.clone()); | |
821 | } | |
822 | ||
823 | pub fn walk_tt<'a, V: Visitor<'a>>(visitor: &mut V, tt: TokenTree) { | |
824 | match tt { | |
825 | TokenTree::Token(_, tok) => visitor.visit_token(tok), | |
826 | TokenTree::Delimited(_, delimed) => visitor.visit_tts(delimed.stream()), | |
827 | } | |
828 | } | |
829 | ||
830 | pub fn walk_tts<'a, V: Visitor<'a>>(visitor: &mut V, tts: TokenStream) { | |
831 | for tt in tts.trees() { | |
832 | visitor.visit_tt(tt); | |
833 | } | |
834 | } |