]>
Commit | Line | Data |
---|---|---|
476ff2be SL |
1 | //! HIR walker for walking the contents of nodes. |
2 | //! | |
3 | //! **For an overview of the visitor strategy, see the docs on the | |
4 | //! `super::itemlikevisit::ItemLikeVisitor` trait.** | |
5 | //! | |
6 | //! If you have decided to use this visitor, here are some general | |
9fa01778 | 7 | //! notes on how to do so: |
476ff2be SL |
8 | //! |
9 | //! Each overridden visit method has full control over what | |
e9174d1e | 10 | //! happens with its node, it can do its own traversal of the node's children, |
9cc50fc6 | 11 | //! call `intravisit::walk_*` to apply the default traversal algorithm, or prevent |
e9174d1e SL |
12 | //! deeper traversal by doing nothing. |
13 | //! | |
92a42be0 SL |
14 | //! When visiting the HIR, the contents of nested items are NOT visited |
15 | //! by default. This is different from the AST visitor, which does a deep walk. | |
16 | //! Hence this module is called `intravisit`; see the method `visit_nested_item` | |
17 | //! for more details. | |
e9174d1e | 18 | //! |
92a42be0 | 19 | //! Note: it is an important invariant that the default visitor walks |
ea8adc8c XL |
20 | //! the body of a function in "execution order" - more concretely, if |
21 | //! we consider the reverse post-order (RPO) of the CFG implied by the HIR, | |
22 | //! then a pre-order traversal of the HIR is consistent with the CFG RPO | |
23 | //! on the *initial CFG point* of each HIR node, while a post-order traversal | |
24 | //! of the HIR is consistent with the CFG RPO on each *final CFG point* of | |
25 | //! each CFG node. | |
26 | //! | |
27 | //! One thing that follows is that if HIR node A always starts/ends executing | |
28 | //! before HIR node B, then A appears in traversal pre/postorder before B, | |
29 | //! respectively. (This follows from RPO respecting CFG domination). | |
30 | //! | |
31 | //! This order consistency is required in a few places in rustc, for | |
32 | //! example generator inference, and possibly also HIR borrowck. | |
e9174d1e | 33 | |
e1599b0c XL |
34 | use super::itemlikevisit::DeepVisitor; |
35 | ||
9fa01778 | 36 | use crate::hir::*; |
9fa01778 | 37 | use crate::hir::map::Map; |
e1599b0c XL |
38 | |
39 | use syntax::ast::{Ident, Name, Attribute}; | |
40 | use syntax_pos::Span; | |
e9174d1e | 41 | |
8faf50e0 | 42 | #[derive(Copy, Clone)] |
e9174d1e | 43 | pub enum FnKind<'a> { |
0731742a XL |
44 | /// `#[xxx] pub async/const/extern "Abi" fn foo()` |
45 | ItemFn(Ident, &'a Generics, FnHeader, &'a Visibility, &'a [Attribute]), | |
e9174d1e | 46 | |
0731742a | 47 | /// `fn foo(&self)` |
8faf50e0 | 48 | Method(Ident, &'a MethodSig, Option<&'a Visibility>, &'a [Attribute]), |
e9174d1e | 49 | |
0731742a | 50 | /// `|x, y| {}` |
54a0048b SL |
51 | Closure(&'a [Attribute]), |
52 | } | |
53 | ||
54 | impl<'a> FnKind<'a> { | |
55 | pub fn attrs(&self) -> &'a [Attribute] { | |
56 | match *self { | |
9e0c209e SL |
57 | FnKind::ItemFn(.., attrs) => attrs, |
58 | FnKind::Method(.., attrs) => attrs, | |
54a0048b SL |
59 | FnKind::Closure(attrs) => attrs, |
60 | } | |
61 | } | |
48663c56 XL |
62 | |
63 | pub fn header(&self) -> Option<&FnHeader> { | |
64 | match *self { | |
65 | FnKind::ItemFn(_, _, ref header, _, _) => Some(header), | |
66 | FnKind::Method(_, ref sig, _, _) => Some(&sig.header), | |
67 | FnKind::Closure(_) => None, | |
68 | } | |
69 | } | |
e9174d1e SL |
70 | } |
71 | ||
476ff2be SL |
72 | /// Specifies what nested things a visitor wants to visit. The most |
73 | /// common choice is `OnlyBodies`, which will cause the visitor to | |
74 | /// visit fn bodies for fns that it encounters, but skip over nested | |
75 | /// item-like things. | |
76 | /// | |
77 | /// See the comments on `ItemLikeVisitor` for more details on the overall | |
78 | /// visit strategy. | |
dc9dc135 | 79 | pub enum NestedVisitorMap<'this, 'tcx> { |
476ff2be SL |
80 | /// Do not visit any nested things. When you add a new |
81 | /// "non-nested" thing, you will want to audit such uses to see if | |
82 | /// they remain valid. | |
83 | /// | |
84 | /// Use this if you are only walking some particular kind of tree | |
85 | /// (i.e., a type, or fn signature) and you don't want to thread a | |
86 | /// HIR map around. | |
87 | None, | |
88 | ||
89 | /// Do not visit nested item-like things, but visit nested things | |
90 | /// that are inside of an item-like. | |
91 | /// | |
3b2f2976 | 92 | /// **This is the most common choice.** A very common pattern is |
7cac9316 | 93 | /// to use `visit_all_item_likes()` as an outer loop, |
476ff2be SL |
94 | /// and to have the visitor that visits the contents of each item |
95 | /// using this setting. | |
96 | OnlyBodies(&'this Map<'tcx>), | |
97 | ||
9fa01778 | 98 | /// Visits all nested things, including item-likes. |
476ff2be SL |
99 | /// |
100 | /// **This is an unusual choice.** It is used when you want to | |
101 | /// process everything within their lexical context. Typically you | |
102 | /// kick off the visit by doing `walk_krate()`. | |
103 | All(&'this Map<'tcx>), | |
104 | } | |
105 | ||
106 | impl<'this, 'tcx> NestedVisitorMap<'this, 'tcx> { | |
107 | /// Returns the map to use for an "intra item-like" thing (if any). | |
9fa01778 | 108 | /// E.g., function body. |
476ff2be SL |
109 | pub fn intra(self) -> Option<&'this Map<'tcx>> { |
110 | match self { | |
111 | NestedVisitorMap::None => None, | |
112 | NestedVisitorMap::OnlyBodies(map) => Some(map), | |
113 | NestedVisitorMap::All(map) => Some(map), | |
114 | } | |
115 | } | |
116 | ||
117 | /// Returns the map to use for an "item-like" thing (if any). | |
9fa01778 | 118 | /// E.g., item, impl-item. |
476ff2be SL |
119 | pub fn inter(self) -> Option<&'this Map<'tcx>> { |
120 | match self { | |
121 | NestedVisitorMap::None => None, | |
122 | NestedVisitorMap::OnlyBodies(_) => None, | |
123 | NestedVisitorMap::All(map) => Some(map), | |
124 | } | |
125 | } | |
126 | } | |
127 | ||
e9174d1e | 128 | /// Each method of the Visitor trait is a hook to be potentially |
9fa01778 | 129 | /// overridden. Each method's default implementation recursively visits |
e9174d1e | 130 | /// the substructure of the input via the corresponding `walk` method; |
0731742a | 131 | /// e.g., the `visit_mod` method by default calls `intravisit::walk_mod`. |
e9174d1e | 132 | /// |
92a42be0 SL |
133 | /// Note that this visitor does NOT visit nested items by default |
134 | /// (this is why the module is called `intravisit`, to distinguish it | |
135 | /// from the AST's `visit` module, which acts differently). If you | |
136 | /// simply want to visit all items in the crate in some order, you | |
137 | /// should call `Crate::visit_all_items`. Otherwise, see the comment | |
138 | /// on `visit_nested_item` for details on how to visit nested items. | |
139 | /// | |
e9174d1e | 140 | /// If you want to ensure that your code handles every variant |
9fa01778 | 141 | /// explicitly, you need to override each method. (And you also need |
e9174d1e SL |
142 | /// to monitor future changes to `Visitor` in case a new method with a |
143 | /// new default implementation gets introduced.) | |
e1599b0c | 144 | pub trait Visitor<'v>: Sized { |
92a42be0 SL |
145 | /////////////////////////////////////////////////////////////////////////// |
146 | // Nested items. | |
147 | ||
476ff2be SL |
148 | /// The default versions of the `visit_nested_XXX` routines invoke |
149 | /// this method to get a map to use. By selecting an enum variant, | |
150 | /// you control which kinds of nested HIR are visited; see | |
151 | /// `NestedVisitorMap` for details. By "nested HIR", we are | |
152 | /// referring to bits of HIR that are not directly embedded within | |
153 | /// one another but rather indirectly, through a table in the | |
154 | /// crate. This is done to control dependencies during incremental | |
155 | /// compilation: the non-inline bits of HIR can be tracked and | |
156 | /// hashed separately. | |
157 | /// | |
158 | /// **If for some reason you want the nested behavior, but don't | |
32a655c1 | 159 | /// have a `Map` at your disposal:** then you should override the |
476ff2be SL |
160 | /// `visit_nested_XXX` methods, and override this method to |
161 | /// `panic!()`. This way, if a new `visit_nested_XXX` variant is | |
162 | /// added in the future, we will see the panic in your code and | |
163 | /// fix it appropriately. | |
164 | fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v>; | |
165 | ||
166 | /// Invoked when a nested item is encountered. By default does | |
e1599b0c XL |
167 | /// nothing unless you override `nested_visit_map` to return other than |
168 | /// `None`, in which case it will walk the item. **You probably | |
476ff2be SL |
169 | /// don't want to override this method** -- instead, override |
170 | /// `nested_visit_map` or use the "shallow" or "deep" visit | |
171 | /// patterns described on `itemlikevisit::ItemLikeVisitor`. The only | |
172 | /// reason to override this method is if you want a nested pattern | |
173 | /// but cannot supply a `Map`; see `nested_visit_map` for advice. | |
92a42be0 SL |
174 | #[allow(unused_variables)] |
175 | fn visit_nested_item(&mut self, id: ItemId) { | |
dc9dc135 | 176 | let opt_item = self.nested_visit_map().inter().map(|map| map.expect_item(id.id)); |
476ff2be SL |
177 | if let Some(item) = opt_item { |
178 | self.visit_item(item); | |
179 | } | |
180 | } | |
181 | ||
32a655c1 SL |
182 | /// Like `visit_nested_item()`, but for trait items. See |
183 | /// `visit_nested_item()` for advice on when to override this | |
184 | /// method. | |
185 | #[allow(unused_variables)] | |
186 | fn visit_nested_trait_item(&mut self, id: TraitItemId) { | |
187 | let opt_item = self.nested_visit_map().inter().map(|map| map.trait_item(id)); | |
188 | if let Some(item) = opt_item { | |
189 | self.visit_trait_item(item); | |
190 | } | |
191 | } | |
192 | ||
476ff2be SL |
193 | /// Like `visit_nested_item()`, but for impl items. See |
194 | /// `visit_nested_item()` for advice on when to override this | |
195 | /// method. | |
196 | #[allow(unused_variables)] | |
197 | fn visit_nested_impl_item(&mut self, id: ImplItemId) { | |
198 | let opt_item = self.nested_visit_map().inter().map(|map| map.impl_item(id)); | |
199 | if let Some(item) = opt_item { | |
200 | self.visit_impl_item(item); | |
201 | } | |
92a42be0 SL |
202 | } |
203 | ||
476ff2be SL |
204 | /// Invoked to visit the body of a function, method or closure. Like |
205 | /// visit_nested_item, does nothing by default unless you override | |
e1599b0c XL |
206 | /// `nested_visit_map` to return other htan `None`, in which case it will walk |
207 | /// the body. | |
32a655c1 SL |
208 | fn visit_nested_body(&mut self, id: BodyId) { |
209 | let opt_body = self.nested_visit_map().intra().map(|map| map.body(id)); | |
210 | if let Some(body) = opt_body { | |
211 | self.visit_body(body); | |
476ff2be SL |
212 | } |
213 | } | |
214 | ||
e1599b0c XL |
215 | fn visit_param(&mut self, param: &'v Param) { |
216 | walk_param(self, param) | |
416331ca XL |
217 | } |
218 | ||
9fa01778 | 219 | /// Visits the top-level item and (optionally) nested items / impl items. See |
92a42be0 SL |
220 | /// `visit_nested_item` for details. |
221 | fn visit_item(&mut self, i: &'v Item) { | |
222 | walk_item(self, i) | |
223 | } | |
224 | ||
32a655c1 SL |
225 | fn visit_body(&mut self, b: &'v Body) { |
226 | walk_body(self, b); | |
227 | } | |
228 | ||
476ff2be | 229 | /// When invoking `visit_all_item_likes()`, you need to supply an |
9fa01778 | 230 | /// item-like visitor. This method converts a "intra-visit" |
476ff2be SL |
231 | /// visitor into an item-like visitor that walks the entire tree. |
232 | /// If you use this, you probably don't want to process the | |
233 | /// contents of nested item-like things, since the outer loop will | |
234 | /// visit them as well. | |
235 | fn as_deep_visitor<'s>(&'s mut self) -> DeepVisitor<'s, Self> { | |
236 | DeepVisitor::new(self) | |
237 | } | |
238 | ||
92a42be0 SL |
239 | /////////////////////////////////////////////////////////////////////////// |
240 | ||
9fa01778 | 241 | fn visit_id(&mut self, _hir_id: HirId) { |
5bcae85e SL |
242 | // Nothing to do. |
243 | } | |
e9174d1e SL |
244 | fn visit_name(&mut self, _span: Span, _name: Name) { |
245 | // Nothing to do. | |
246 | } | |
94b46f34 XL |
247 | fn visit_ident(&mut self, ident: Ident) { |
248 | walk_ident(self, ident) | |
249 | } | |
9fa01778 | 250 | fn visit_mod(&mut self, m: &'v Mod, _s: Span, n: HirId) { |
5bcae85e | 251 | walk_mod(self, m, n) |
b039eaaf SL |
252 | } |
253 | fn visit_foreign_item(&mut self, i: &'v ForeignItem) { | |
254 | walk_foreign_item(self, i) | |
255 | } | |
b039eaaf SL |
256 | fn visit_local(&mut self, l: &'v Local) { |
257 | walk_local(self, l) | |
258 | } | |
259 | fn visit_block(&mut self, b: &'v Block) { | |
260 | walk_block(self, b) | |
261 | } | |
262 | fn visit_stmt(&mut self, s: &'v Stmt) { | |
263 | walk_stmt(self, s) | |
264 | } | |
265 | fn visit_arm(&mut self, a: &'v Arm) { | |
266 | walk_arm(self, a) | |
267 | } | |
268 | fn visit_pat(&mut self, p: &'v Pat) { | |
269 | walk_pat(self, p) | |
270 | } | |
94b46f34 XL |
271 | fn visit_anon_const(&mut self, c: &'v AnonConst) { |
272 | walk_anon_const(self, c) | |
273 | } | |
b039eaaf SL |
274 | fn visit_expr(&mut self, ex: &'v Expr) { |
275 | walk_expr(self, ex) | |
276 | } | |
b039eaaf SL |
277 | fn visit_ty(&mut self, t: &'v Ty) { |
278 | walk_ty(self, t) | |
279 | } | |
ff7c6d11 XL |
280 | fn visit_generic_param(&mut self, p: &'v GenericParam) { |
281 | walk_generic_param(self, p) | |
282 | } | |
b039eaaf SL |
283 | fn visit_generics(&mut self, g: &'v Generics) { |
284 | walk_generics(self, g) | |
285 | } | |
3157f602 XL |
286 | fn visit_where_predicate(&mut self, predicate: &'v WherePredicate) { |
287 | walk_where_predicate(self, predicate) | |
288 | } | |
32a655c1 SL |
289 | fn visit_fn_decl(&mut self, fd: &'v FnDecl) { |
290 | walk_fn_decl(self, fd) | |
291 | } | |
9fa01778 | 292 | fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: BodyId, s: Span, id: HirId) { |
5bcae85e | 293 | walk_fn(self, fk, fd, b, s, id) |
e9174d1e | 294 | } |
9fa01778 XL |
295 | fn visit_use(&mut self, path: &'v Path, hir_id: HirId) { |
296 | walk_use(self, path, hir_id) | |
13cf67c4 | 297 | } |
b039eaaf SL |
298 | fn visit_trait_item(&mut self, ti: &'v TraitItem) { |
299 | walk_trait_item(self, ti) | |
300 | } | |
32a655c1 SL |
301 | fn visit_trait_item_ref(&mut self, ii: &'v TraitItemRef) { |
302 | walk_trait_item_ref(self, ii) | |
303 | } | |
b039eaaf SL |
304 | fn visit_impl_item(&mut self, ii: &'v ImplItem) { |
305 | walk_impl_item(self, ii) | |
306 | } | |
476ff2be SL |
307 | fn visit_impl_item_ref(&mut self, ii: &'v ImplItemRef) { |
308 | walk_impl_item_ref(self, ii) | |
309 | } | |
b039eaaf SL |
310 | fn visit_trait_ref(&mut self, t: &'v TraitRef) { |
311 | walk_trait_ref(self, t) | |
312 | } | |
8faf50e0 XL |
313 | fn visit_param_bound(&mut self, bounds: &'v GenericBound) { |
314 | walk_param_bound(self, bounds) | |
e9174d1e | 315 | } |
32a655c1 | 316 | fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef, m: TraitBoundModifier) { |
e9174d1e SL |
317 | walk_poly_trait_ref(self, t, m) |
318 | } | |
92a42be0 SL |
319 | fn visit_variant_data(&mut self, |
320 | s: &'v VariantData, | |
321 | _: Name, | |
322 | _: &'v Generics, | |
9fa01778 | 323 | _parent_id: HirId, |
92a42be0 | 324 | _: Span) { |
e9174d1e SL |
325 | walk_struct_def(self, s) |
326 | } | |
b039eaaf SL |
327 | fn visit_struct_field(&mut self, s: &'v StructField) { |
328 | walk_struct_field(self, s) | |
e9174d1e | 329 | } |
92a42be0 SL |
330 | fn visit_enum_def(&mut self, |
331 | enum_definition: &'v EnumDef, | |
332 | generics: &'v Generics, | |
9fa01778 | 333 | item_id: HirId, |
92a42be0 | 334 | _: Span) { |
b039eaaf | 335 | walk_enum_def(self, enum_definition, generics, item_id) |
e9174d1e | 336 | } |
9fa01778 | 337 | fn visit_variant(&mut self, v: &'v Variant, g: &'v Generics, item_id: HirId) { |
b039eaaf | 338 | walk_variant(self, v, g, item_id) |
e9174d1e | 339 | } |
2c00a5a8 XL |
340 | fn visit_label(&mut self, label: &'v Label) { |
341 | walk_label(self, label) | |
342 | } | |
8faf50e0 XL |
343 | fn visit_generic_arg(&mut self, generic_arg: &'v GenericArg) { |
344 | match generic_arg { | |
345 | GenericArg::Lifetime(lt) => self.visit_lifetime(lt), | |
346 | GenericArg::Type(ty) => self.visit_ty(ty), | |
9fa01778 | 347 | GenericArg::Const(ct) => self.visit_anon_const(&ct.value), |
8faf50e0 XL |
348 | } |
349 | } | |
b039eaaf SL |
350 | fn visit_lifetime(&mut self, lifetime: &'v Lifetime) { |
351 | walk_lifetime(self, lifetime) | |
e9174d1e | 352 | } |
b7449926 | 353 | fn visit_qpath(&mut self, qpath: &'v QPath, id: HirId, span: Span) { |
476ff2be SL |
354 | walk_qpath(self, qpath, id, span) |
355 | } | |
b7449926 | 356 | fn visit_path(&mut self, path: &'v Path, _id: HirId) { |
e9174d1e SL |
357 | walk_path(self, path) |
358 | } | |
359 | fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment) { | |
360 | walk_path_segment(self, path_span, path_segment) | |
361 | } | |
8faf50e0 XL |
362 | fn visit_generic_args(&mut self, path_span: Span, generic_args: &'v GenericArgs) { |
363 | walk_generic_args(self, path_span, generic_args) | |
e9174d1e SL |
364 | } |
365 | fn visit_assoc_type_binding(&mut self, type_binding: &'v TypeBinding) { | |
366 | walk_assoc_type_binding(self, type_binding) | |
367 | } | |
b039eaaf SL |
368 | fn visit_attribute(&mut self, _attr: &'v Attribute) { |
369 | } | |
370 | fn visit_macro_def(&mut self, macro_def: &'v MacroDef) { | |
371 | walk_macro_def(self, macro_def) | |
372 | } | |
a7813a04 XL |
373 | fn visit_vis(&mut self, vis: &'v Visibility) { |
374 | walk_vis(self, vis) | |
375 | } | |
dc9dc135 | 376 | fn visit_associated_item_kind(&mut self, kind: &'v AssocItemKind) { |
476ff2be SL |
377 | walk_associated_item_kind(self, kind); |
378 | } | |
379 | fn visit_defaultness(&mut self, defaultness: &'v Defaultness) { | |
380 | walk_defaultness(self, defaultness); | |
381 | } | |
e9174d1e SL |
382 | } |
383 | ||
92a42be0 | 384 | /// Walks the contents of a crate. See also `Crate::visit_all_items`. |
b039eaaf | 385 | pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate) { |
9fa01778 | 386 | visitor.visit_mod(&krate.module, krate.span, CRATE_HIR_ID); |
b039eaaf SL |
387 | walk_list!(visitor, visit_attribute, &krate.attrs); |
388 | walk_list!(visitor, visit_macro_def, &krate.exported_macros); | |
389 | } | |
390 | ||
391 | pub fn walk_macro_def<'v, V: Visitor<'v>>(visitor: &mut V, macro_def: &'v MacroDef) { | |
9fa01778 | 392 | visitor.visit_id(macro_def.hir_id); |
b039eaaf | 393 | visitor.visit_name(macro_def.span, macro_def.name); |
b039eaaf SL |
394 | walk_list!(visitor, visit_attribute, ¯o_def.attrs); |
395 | } | |
396 | ||
9fa01778 XL |
397 | pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod, mod_hir_id: HirId) { |
398 | visitor.visit_id(mod_hir_id); | |
92a42be0 SL |
399 | for &item_id in &module.item_ids { |
400 | visitor.visit_nested_item(item_id); | |
401 | } | |
e9174d1e SL |
402 | } |
403 | ||
32a655c1 | 404 | pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &'v Body) { |
e1599b0c | 405 | walk_list!(visitor, visit_param, &body.params); |
32a655c1 SL |
406 | visitor.visit_expr(&body.value); |
407 | } | |
408 | ||
b039eaaf | 409 | pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) { |
ea8adc8c XL |
410 | // Intentionally visiting the expr first - the initialization expr |
411 | // dominates the local's definition. | |
412 | walk_list!(visitor, visit_expr, &local.init); | |
0531ce1d | 413 | walk_list!(visitor, visit_attribute, local.attrs.iter()); |
9fa01778 | 414 | visitor.visit_id(local.hir_id); |
b039eaaf SL |
415 | visitor.visit_pat(&local.pat); |
416 | walk_list!(visitor, visit_ty, &local.ty); | |
b039eaaf SL |
417 | } |
418 | ||
94b46f34 XL |
419 | pub fn walk_ident<'v, V: Visitor<'v>>(visitor: &mut V, ident: Ident) { |
420 | visitor.visit_name(ident.span, ident.name); | |
421 | } | |
422 | ||
2c00a5a8 | 423 | pub fn walk_label<'v, V: Visitor<'v>>(visitor: &mut V, label: &'v Label) { |
8faf50e0 | 424 | visitor.visit_ident(label.ident); |
2c00a5a8 XL |
425 | } |
426 | ||
b039eaaf | 427 | pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) { |
9fa01778 | 428 | visitor.visit_id(lifetime.hir_id); |
ea8adc8c | 429 | match lifetime.name { |
8faf50e0 XL |
430 | LifetimeName::Param(ParamName::Plain(ident)) => { |
431 | visitor.visit_ident(ident); | |
ea8adc8c | 432 | } |
8faf50e0 | 433 | LifetimeName::Param(ParamName::Fresh(_)) | |
0bf4aa26 | 434 | LifetimeName::Param(ParamName::Error) | |
0531ce1d | 435 | LifetimeName::Static | |
0bf4aa26 | 436 | LifetimeName::Error | |
0531ce1d | 437 | LifetimeName::Implicit | |
e1599b0c | 438 | LifetimeName::ImplicitObjectLifetimeDefault | |
0531ce1d | 439 | LifetimeName::Underscore => {} |
ea8adc8c | 440 | } |
e9174d1e SL |
441 | } |
442 | ||
e9174d1e SL |
443 | pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V, |
444 | trait_ref: &'v PolyTraitRef, | |
32a655c1 | 445 | _modifier: TraitBoundModifier) |
e9174d1e SL |
446 | where V: Visitor<'v> |
447 | { | |
ff7c6d11 | 448 | walk_list!(visitor, visit_generic_param, &trait_ref.bound_generic_params); |
e9174d1e SL |
449 | visitor.visit_trait_ref(&trait_ref.trait_ref); |
450 | } | |
451 | ||
b039eaaf | 452 | pub fn walk_trait_ref<'v, V>(visitor: &mut V, trait_ref: &'v TraitRef) |
e9174d1e SL |
453 | where V: Visitor<'v> |
454 | { | |
9fa01778 | 455 | visitor.visit_id(trait_ref.hir_ref_id); |
b7449926 | 456 | visitor.visit_path(&trait_ref.path, trait_ref.hir_ref_id) |
e9174d1e SL |
457 | } |
458 | ||
e1599b0c XL |
459 | pub fn walk_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Param) { |
460 | visitor.visit_id(param.hir_id); | |
461 | visitor.visit_pat(¶m.pat); | |
462 | walk_list!(visitor, visit_attribute, ¶m.attrs); | |
416331ca XL |
463 | } |
464 | ||
e9174d1e | 465 | pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { |
a7813a04 | 466 | visitor.visit_vis(&item.vis); |
0731742a | 467 | visitor.visit_ident(item.ident); |
e9174d1e | 468 | match item.node { |
8faf50e0 | 469 | ItemKind::ExternCrate(orig_name) => { |
9fa01778 | 470 | visitor.visit_id(item.hir_id); |
0531ce1d XL |
471 | if let Some(orig_name) = orig_name { |
472 | visitor.visit_name(item.span, orig_name); | |
2c00a5a8 | 473 | } |
b039eaaf | 474 | } |
8faf50e0 | 475 | ItemKind::Use(ref path, _) => { |
9fa01778 | 476 | visitor.visit_use(path, item.hir_id); |
e9174d1e | 477 | } |
8faf50e0 XL |
478 | ItemKind::Static(ref typ, _, body) | |
479 | ItemKind::Const(ref typ, body) => { | |
9fa01778 | 480 | visitor.visit_id(item.hir_id); |
b039eaaf | 481 | visitor.visit_ty(typ); |
32a655c1 | 482 | visitor.visit_nested_body(body); |
e9174d1e | 483 | } |
8faf50e0 | 484 | ItemKind::Fn(ref declaration, header, ref generics, body_id) => { |
0731742a | 485 | visitor.visit_fn(FnKind::ItemFn(item.ident, |
b039eaaf | 486 | generics, |
8faf50e0 | 487 | header, |
54a0048b SL |
488 | &item.vis, |
489 | &item.attrs), | |
b039eaaf | 490 | declaration, |
476ff2be | 491 | body_id, |
e9174d1e | 492 | item.span, |
9fa01778 | 493 | item.hir_id) |
e9174d1e | 494 | } |
8faf50e0 | 495 | ItemKind::Mod(ref module) => { |
9fa01778 XL |
496 | // `visit_mod()` takes care of visiting the `Item`'s `HirId`. |
497 | visitor.visit_mod(module, item.span, item.hir_id) | |
e9174d1e | 498 | } |
8faf50e0 | 499 | ItemKind::ForeignMod(ref foreign_module) => { |
9fa01778 | 500 | visitor.visit_id(item.hir_id); |
b039eaaf | 501 | walk_list!(visitor, visit_foreign_item, &foreign_module.items); |
e9174d1e | 502 | } |
8faf50e0 | 503 | ItemKind::GlobalAsm(_) => { |
9fa01778 | 504 | visitor.visit_id(item.hir_id); |
cc61c64b | 505 | } |
416331ca | 506 | ItemKind::TyAlias(ref ty, ref generics) => { |
9fa01778 | 507 | visitor.visit_id(item.hir_id); |
532ac7d7 XL |
508 | visitor.visit_ty(ty); |
509 | visitor.visit_generics(generics) | |
e9174d1e | 510 | } |
416331ca | 511 | ItemKind::OpaqueTy(OpaqueTy { |
532ac7d7 XL |
512 | ref generics, |
513 | ref bounds, | |
514 | .. | |
515 | }) => { | |
9fa01778 | 516 | visitor.visit_id(item.hir_id); |
94b46f34 | 517 | walk_generics(visitor, generics); |
8faf50e0 | 518 | walk_list!(visitor, visit_param_bound, bounds); |
94b46f34 | 519 | } |
532ac7d7 XL |
520 | ItemKind::Enum(ref enum_definition, ref generics) => { |
521 | visitor.visit_generics(generics); | |
9fa01778 | 522 | // `visit_enum_def()` takes care of visiting the `Item`'s `HirId`. |
532ac7d7 | 523 | visitor.visit_enum_def(enum_definition, generics, item.hir_id, item.span) |
e9174d1e | 524 | } |
8faf50e0 XL |
525 | ItemKind::Impl( |
526 | .., | |
532ac7d7 | 527 | ref generics, |
8faf50e0 XL |
528 | ref opt_trait_reference, |
529 | ref typ, | |
530 | ref impl_item_refs | |
531 | ) => { | |
9fa01778 | 532 | visitor.visit_id(item.hir_id); |
532ac7d7 | 533 | visitor.visit_generics(generics); |
b039eaaf SL |
534 | walk_list!(visitor, visit_trait_ref, opt_trait_reference); |
535 | visitor.visit_ty(typ); | |
32a655c1 | 536 | walk_list!(visitor, visit_impl_item_ref, impl_item_refs); |
e9174d1e | 537 | } |
8faf50e0 XL |
538 | ItemKind::Struct(ref struct_definition, ref generics) | |
539 | ItemKind::Union(ref struct_definition, ref generics) => { | |
e9174d1e | 540 | visitor.visit_generics(generics); |
9fa01778 XL |
541 | visitor.visit_id(item.hir_id); |
542 | visitor.visit_variant_data(struct_definition, item.ident.name, generics, item.hir_id, | |
0731742a | 543 | item.span); |
e9174d1e | 544 | } |
8faf50e0 | 545 | ItemKind::Trait(.., ref generics, ref bounds, ref trait_item_refs) => { |
9fa01778 | 546 | visitor.visit_id(item.hir_id); |
e9174d1e | 547 | visitor.visit_generics(generics); |
8faf50e0 | 548 | walk_list!(visitor, visit_param_bound, bounds); |
32a655c1 | 549 | walk_list!(visitor, visit_trait_item_ref, trait_item_refs); |
e9174d1e | 550 | } |
8faf50e0 | 551 | ItemKind::TraitAlias(ref generics, ref bounds) => { |
9fa01778 | 552 | visitor.visit_id(item.hir_id); |
ff7c6d11 | 553 | visitor.visit_generics(generics); |
8faf50e0 | 554 | walk_list!(visitor, visit_param_bound, bounds); |
ff7c6d11 | 555 | } |
e9174d1e | 556 | } |
b039eaaf | 557 | walk_list!(visitor, visit_attribute, &item.attrs); |
e9174d1e SL |
558 | } |
559 | ||
13cf67c4 XL |
560 | pub fn walk_use<'v, V: Visitor<'v>>(visitor: &mut V, |
561 | path: &'v Path, | |
13cf67c4 | 562 | hir_id: HirId) { |
9fa01778 | 563 | visitor.visit_id(hir_id); |
13cf67c4 XL |
564 | visitor.visit_path(path, hir_id); |
565 | } | |
566 | ||
e9174d1e SL |
567 | pub fn walk_enum_def<'v, V: Visitor<'v>>(visitor: &mut V, |
568 | enum_definition: &'v EnumDef, | |
b039eaaf | 569 | generics: &'v Generics, |
9fa01778 | 570 | item_id: HirId) { |
5bcae85e | 571 | visitor.visit_id(item_id); |
92a42be0 SL |
572 | walk_list!(visitor, |
573 | visit_variant, | |
574 | &enum_definition.variants, | |
575 | generics, | |
576 | item_id); | |
e9174d1e SL |
577 | } |
578 | ||
579 | pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V, | |
580 | variant: &'v Variant, | |
b039eaaf | 581 | generics: &'v Generics, |
9fa01778 | 582 | parent_item_id: HirId) { |
e1599b0c XL |
583 | visitor.visit_ident(variant.ident); |
584 | visitor.visit_id(variant.id); | |
585 | visitor.visit_variant_data(&variant.data, | |
586 | variant.ident.name, | |
92a42be0 | 587 | generics, |
5bcae85e | 588 | parent_item_id, |
92a42be0 | 589 | variant.span); |
e1599b0c XL |
590 | walk_list!(visitor, visit_anon_const, &variant.disr_expr); |
591 | walk_list!(visitor, visit_attribute, &variant.attrs); | |
e9174d1e SL |
592 | } |
593 | ||
594 | pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { | |
9fa01778 | 595 | visitor.visit_id(typ.hir_id); |
5bcae85e | 596 | |
e9174d1e | 597 | match typ.node { |
8faf50e0 | 598 | TyKind::Slice(ref ty) => { |
b039eaaf | 599 | visitor.visit_ty(ty) |
e9174d1e | 600 | } |
8faf50e0 | 601 | TyKind::Ptr(ref mutable_type) => { |
b039eaaf | 602 | visitor.visit_ty(&mutable_type.ty) |
e9174d1e | 603 | } |
8faf50e0 | 604 | TyKind::Rptr(ref lifetime, ref mutable_type) => { |
32a655c1 | 605 | visitor.visit_lifetime(lifetime); |
b039eaaf | 606 | visitor.visit_ty(&mutable_type.ty) |
e9174d1e | 607 | } |
e1599b0c | 608 | TyKind::Never => {} |
8faf50e0 | 609 | TyKind::Tup(ref tuple_element_types) => { |
b039eaaf | 610 | walk_list!(visitor, visit_ty, tuple_element_types); |
e9174d1e | 611 | } |
8faf50e0 | 612 | TyKind::BareFn(ref function_declaration) => { |
ff7c6d11 | 613 | walk_list!(visitor, visit_generic_param, &function_declaration.generic_params); |
94b46f34 | 614 | visitor.visit_fn_decl(&function_declaration.decl); |
e9174d1e | 615 | } |
8faf50e0 | 616 | TyKind::Path(ref qpath) => { |
b7449926 | 617 | visitor.visit_qpath(qpath, typ.hir_id, typ.span); |
e9174d1e | 618 | } |
0bf4aa26 XL |
619 | TyKind::Def(item_id, ref lifetimes) => { |
620 | visitor.visit_nested_item(item_id); | |
621 | walk_list!(visitor, visit_generic_arg, lifetimes); | |
622 | } | |
8faf50e0 | 623 | TyKind::Array(ref ty, ref length) => { |
b039eaaf | 624 | visitor.visit_ty(ty); |
94b46f34 | 625 | visitor.visit_anon_const(length) |
e9174d1e | 626 | } |
8faf50e0 | 627 | TyKind::TraitObject(ref bounds, ref lifetime) => { |
32a655c1 SL |
628 | for bound in bounds { |
629 | visitor.visit_poly_trait_ref(bound, TraitBoundModifier::None); | |
630 | } | |
631 | visitor.visit_lifetime(lifetime); | |
e9174d1e | 632 | } |
8faf50e0 | 633 | TyKind::Typeof(ref expression) => { |
94b46f34 | 634 | visitor.visit_anon_const(expression) |
e9174d1e | 635 | } |
532ac7d7 XL |
636 | TyKind::CVarArgs(ref lt) => { |
637 | visitor.visit_lifetime(lt) | |
638 | } | |
8faf50e0 | 639 | TyKind::Infer | TyKind::Err => {} |
e9174d1e SL |
640 | } |
641 | } | |
642 | ||
b7449926 | 643 | pub fn walk_qpath<'v, V: Visitor<'v>>(visitor: &mut V, qpath: &'v QPath, id: HirId, span: Span) { |
476ff2be SL |
644 | match *qpath { |
645 | QPath::Resolved(ref maybe_qself, ref path) => { | |
646 | if let Some(ref qself) = *maybe_qself { | |
647 | visitor.visit_ty(qself); | |
648 | } | |
649 | visitor.visit_path(path, id) | |
650 | } | |
651 | QPath::TypeRelative(ref qself, ref segment) => { | |
652 | visitor.visit_ty(qself); | |
653 | visitor.visit_path_segment(span, segment); | |
654 | } | |
655 | } | |
656 | } | |
657 | ||
e9174d1e SL |
658 | pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) { |
659 | for segment in &path.segments { | |
660 | visitor.visit_path_segment(path.span, segment); | |
661 | } | |
662 | } | |
663 | ||
664 | pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V, | |
665 | path_span: Span, | |
666 | segment: &'v PathSegment) { | |
8faf50e0 | 667 | visitor.visit_ident(segment.ident); |
9fa01778 | 668 | if let Some(id) = segment.hir_id { |
13cf67c4 XL |
669 | visitor.visit_id(id); |
670 | } | |
8faf50e0 XL |
671 | if let Some(ref args) = segment.args { |
672 | visitor.visit_generic_args(path_span, args); | |
ea8adc8c | 673 | } |
e9174d1e SL |
674 | } |
675 | ||
8faf50e0 XL |
676 | pub fn walk_generic_args<'v, V: Visitor<'v>>(visitor: &mut V, |
677 | _path_span: Span, | |
678 | generic_args: &'v GenericArgs) { | |
679 | walk_list!(visitor, visit_generic_arg, &generic_args.args); | |
680 | walk_list!(visitor, visit_assoc_type_binding, &generic_args.bindings); | |
e9174d1e SL |
681 | } |
682 | ||
683 | pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(visitor: &mut V, | |
684 | type_binding: &'v TypeBinding) { | |
9fa01778 | 685 | visitor.visit_id(type_binding.hir_id); |
8faf50e0 | 686 | visitor.visit_ident(type_binding.ident); |
dc9dc135 XL |
687 | match type_binding.kind { |
688 | TypeBindingKind::Equality { ref ty } => { | |
689 | visitor.visit_ty(ty); | |
690 | } | |
691 | TypeBindingKind::Constraint { ref bounds } => { | |
692 | walk_list!(visitor, visit_param_bound, bounds); | |
693 | } | |
694 | } | |
e9174d1e SL |
695 | } |
696 | ||
697 | pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) { | |
9fa01778 | 698 | visitor.visit_id(pattern.hir_id); |
e9174d1e | 699 | match pattern.node { |
476ff2be | 700 | PatKind::TupleStruct(ref qpath, ref children, _) => { |
b7449926 | 701 | visitor.visit_qpath(qpath, pattern.hir_id, pattern.span); |
3157f602 | 702 | walk_list!(visitor, visit_pat, children); |
e9174d1e | 703 | } |
476ff2be | 704 | PatKind::Path(ref qpath) => { |
b7449926 | 705 | visitor.visit_qpath(qpath, pattern.hir_id, pattern.span); |
e9174d1e | 706 | } |
476ff2be | 707 | PatKind::Struct(ref qpath, ref fields, _) => { |
b7449926 | 708 | visitor.visit_qpath(qpath, pattern.hir_id, pattern.span); |
e9174d1e | 709 | for field in fields { |
e1599b0c XL |
710 | visitor.visit_id(field.hir_id); |
711 | visitor.visit_ident(field.ident); | |
712 | visitor.visit_pat(&field.pat) | |
e9174d1e SL |
713 | } |
714 | } | |
e1599b0c | 715 | PatKind::Or(ref pats) => walk_list!(visitor, visit_pat, pats), |
3157f602 | 716 | PatKind::Tuple(ref tuple_elements, _) => { |
b039eaaf | 717 | walk_list!(visitor, visit_pat, tuple_elements); |
e9174d1e | 718 | } |
7453a54e SL |
719 | PatKind::Box(ref subpattern) | |
720 | PatKind::Ref(ref subpattern, _) => { | |
b039eaaf | 721 | visitor.visit_pat(subpattern) |
e9174d1e | 722 | } |
532ac7d7 | 723 | PatKind::Binding(_, _hir_id, ident, ref optional_subpattern) => { |
8faf50e0 | 724 | visitor.visit_ident(ident); |
b039eaaf | 725 | walk_list!(visitor, visit_pat, optional_subpattern); |
e9174d1e | 726 | } |
7453a54e | 727 | PatKind::Lit(ref expression) => visitor.visit_expr(expression), |
32a655c1 | 728 | PatKind::Range(ref lower_bound, ref upper_bound, _) => { |
b039eaaf SL |
729 | visitor.visit_expr(lower_bound); |
730 | visitor.visit_expr(upper_bound) | |
e9174d1e | 731 | } |
7453a54e | 732 | PatKind::Wild => (), |
c30ab7b3 | 733 | PatKind::Slice(ref prepatterns, ref slice_pattern, ref postpatterns) => { |
b039eaaf SL |
734 | walk_list!(visitor, visit_pat, prepatterns); |
735 | walk_list!(visitor, visit_pat, slice_pattern); | |
736 | walk_list!(visitor, visit_pat, postpatterns); | |
e9174d1e SL |
737 | } |
738 | } | |
739 | } | |
740 | ||
b039eaaf | 741 | pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v ForeignItem) { |
9fa01778 | 742 | visitor.visit_id(foreign_item.hir_id); |
a7813a04 | 743 | visitor.visit_vis(&foreign_item.vis); |
0731742a | 744 | visitor.visit_ident(foreign_item.ident); |
e9174d1e SL |
745 | |
746 | match foreign_item.node { | |
8faf50e0 | 747 | ForeignItemKind::Fn(ref function_declaration, ref param_names, ref generics) => { |
32a655c1 SL |
748 | visitor.visit_generics(generics); |
749 | visitor.visit_fn_decl(function_declaration); | |
8faf50e0 XL |
750 | for ¶m_name in param_names { |
751 | visitor.visit_ident(param_name); | |
32a655c1 | 752 | } |
e9174d1e | 753 | } |
8faf50e0 XL |
754 | ForeignItemKind::Static(ref typ, _) => visitor.visit_ty(typ), |
755 | ForeignItemKind::Type => (), | |
e9174d1e SL |
756 | } |
757 | ||
b039eaaf | 758 | walk_list!(visitor, visit_attribute, &foreign_item.attrs); |
e9174d1e SL |
759 | } |
760 | ||
8faf50e0 | 761 | pub fn walk_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v GenericBound) { |
e9174d1e | 762 | match *bound { |
8faf50e0 | 763 | GenericBound::Trait(ref typ, modifier) => { |
e9174d1e SL |
764 | visitor.visit_poly_trait_ref(typ, modifier); |
765 | } | |
8faf50e0 | 766 | GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime), |
e9174d1e SL |
767 | } |
768 | } | |
769 | ||
ff7c6d11 | 770 | pub fn walk_generic_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v GenericParam) { |
9fa01778 | 771 | visitor.visit_id(param.hir_id); |
8faf50e0 XL |
772 | walk_list!(visitor, visit_attribute, ¶m.attrs); |
773 | match param.name { | |
774 | ParamName::Plain(ident) => visitor.visit_ident(ident), | |
0bf4aa26 | 775 | ParamName::Error | ParamName::Fresh(_) => {} |
e9174d1e | 776 | } |
8faf50e0 XL |
777 | match param.kind { |
778 | GenericParamKind::Lifetime { .. } => {} | |
779 | GenericParamKind::Type { ref default, .. } => walk_list!(visitor, visit_ty, default), | |
9fa01778 | 780 | GenericParamKind::Const { ref ty } => visitor.visit_ty(ty), |
8faf50e0 XL |
781 | } |
782 | walk_list!(visitor, visit_param_bound, ¶m.bounds); | |
ff7c6d11 XL |
783 | } |
784 | ||
785 | pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics) { | |
786 | walk_list!(visitor, visit_generic_param, &generics.params); | |
3157f602 XL |
787 | walk_list!(visitor, visit_where_predicate, &generics.where_clause.predicates); |
788 | } | |
789 | ||
790 | pub fn walk_where_predicate<'v, V: Visitor<'v>>( | |
791 | visitor: &mut V, | |
792 | predicate: &'v WherePredicate) | |
793 | { | |
794 | match predicate { | |
795 | &WherePredicate::BoundPredicate(WhereBoundPredicate{ref bounded_ty, | |
796 | ref bounds, | |
ff7c6d11 | 797 | ref bound_generic_params, |
3157f602 XL |
798 | ..}) => { |
799 | visitor.visit_ty(bounded_ty); | |
8faf50e0 | 800 | walk_list!(visitor, visit_param_bound, bounds); |
ff7c6d11 | 801 | walk_list!(visitor, visit_generic_param, bound_generic_params); |
3157f602 XL |
802 | } |
803 | &WherePredicate::RegionPredicate(WhereRegionPredicate{ref lifetime, | |
804 | ref bounds, | |
805 | ..}) => { | |
806 | visitor.visit_lifetime(lifetime); | |
8faf50e0 | 807 | walk_list!(visitor, visit_param_bound, bounds); |
3157f602 | 808 | } |
9fa01778 | 809 | &WherePredicate::EqPredicate(WhereEqPredicate{hir_id, |
32a655c1 SL |
810 | ref lhs_ty, |
811 | ref rhs_ty, | |
3157f602 | 812 | ..}) => { |
9fa01778 | 813 | visitor.visit_id(hir_id); |
32a655c1 SL |
814 | visitor.visit_ty(lhs_ty); |
815 | visitor.visit_ty(rhs_ty); | |
e9174d1e SL |
816 | } |
817 | } | |
818 | } | |
819 | ||
820 | pub fn walk_fn_ret_ty<'v, V: Visitor<'v>>(visitor: &mut V, ret_ty: &'v FunctionRetTy) { | |
821 | if let Return(ref output_ty) = *ret_ty { | |
b039eaaf | 822 | visitor.visit_ty(output_ty) |
e9174d1e SL |
823 | } |
824 | } | |
825 | ||
826 | pub fn walk_fn_decl<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: &'v FnDecl) { | |
32a655c1 SL |
827 | for ty in &function_declaration.inputs { |
828 | visitor.visit_ty(ty) | |
b039eaaf SL |
829 | } |
830 | walk_fn_ret_ty(visitor, &function_declaration.output) | |
831 | } | |
832 | ||
833 | pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'v>) { | |
e9174d1e | 834 | match function_kind { |
9e0c209e | 835 | FnKind::ItemFn(_, generics, ..) => { |
e9174d1e SL |
836 | visitor.visit_generics(generics); |
837 | } | |
abe05a73 | 838 | FnKind::Method(..) | |
54a0048b | 839 | FnKind::Closure(_) => {} |
e9174d1e SL |
840 | } |
841 | } | |
842 | ||
843 | pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V, | |
844 | function_kind: FnKind<'v>, | |
845 | function_declaration: &'v FnDecl, | |
32a655c1 | 846 | body_id: BodyId, |
5bcae85e | 847 | _span: Span, |
9fa01778 | 848 | id: HirId) { |
5bcae85e | 849 | visitor.visit_id(id); |
32a655c1 | 850 | visitor.visit_fn_decl(function_declaration); |
e9174d1e | 851 | walk_fn_kind(visitor, function_kind); |
32a655c1 | 852 | visitor.visit_nested_body(body_id) |
e9174d1e SL |
853 | } |
854 | ||
855 | pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem) { | |
8faf50e0 | 856 | visitor.visit_ident(trait_item.ident); |
b039eaaf | 857 | walk_list!(visitor, visit_attribute, &trait_item.attrs); |
abe05a73 | 858 | visitor.visit_generics(&trait_item.generics); |
e9174d1e | 859 | match trait_item.node { |
32a655c1 | 860 | TraitItemKind::Const(ref ty, default) => { |
9fa01778 | 861 | visitor.visit_id(trait_item.hir_id); |
e9174d1e | 862 | visitor.visit_ty(ty); |
32a655c1 | 863 | walk_list!(visitor, visit_nested_body, default); |
e9174d1e | 864 | } |
8faf50e0 | 865 | TraitItemKind::Method(ref sig, TraitMethod::Required(ref param_names)) => { |
9fa01778 | 866 | visitor.visit_id(trait_item.hir_id); |
32a655c1 | 867 | visitor.visit_fn_decl(&sig.decl); |
8faf50e0 XL |
868 | for ¶m_name in param_names { |
869 | visitor.visit_ident(param_name); | |
32a655c1 | 870 | } |
e9174d1e | 871 | } |
32a655c1 | 872 | TraitItemKind::Method(ref sig, TraitMethod::Provided(body_id)) => { |
8faf50e0 | 873 | visitor.visit_fn(FnKind::Method(trait_item.ident, |
54a0048b SL |
874 | sig, |
875 | None, | |
876 | &trait_item.attrs), | |
b039eaaf | 877 | &sig.decl, |
476ff2be | 878 | body_id, |
b039eaaf | 879 | trait_item.span, |
9fa01778 | 880 | trait_item.hir_id); |
e9174d1e | 881 | } |
32a655c1 | 882 | TraitItemKind::Type(ref bounds, ref default) => { |
9fa01778 | 883 | visitor.visit_id(trait_item.hir_id); |
8faf50e0 | 884 | walk_list!(visitor, visit_param_bound, bounds); |
b039eaaf | 885 | walk_list!(visitor, visit_ty, default); |
e9174d1e SL |
886 | } |
887 | } | |
888 | } | |
889 | ||
32a655c1 | 890 | pub fn walk_trait_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, trait_item_ref: &'v TraitItemRef) { |
0731742a | 891 | // N.B., deliberately force a compilation error if/when new fields are added. |
8faf50e0 | 892 | let TraitItemRef { id, ident, ref kind, span: _, ref defaultness } = *trait_item_ref; |
32a655c1 | 893 | visitor.visit_nested_trait_item(id); |
8faf50e0 | 894 | visitor.visit_ident(ident); |
32a655c1 SL |
895 | visitor.visit_associated_item_kind(kind); |
896 | visitor.visit_defaultness(defaultness); | |
897 | } | |
898 | ||
e9174d1e | 899 | pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem) { |
0731742a | 900 | // N.B., deliberately force a compilation error if/when new fields are added. |
3b2f2976 | 901 | let ImplItem { |
3b2f2976 | 902 | hir_id: _, |
8faf50e0 | 903 | ident, |
3b2f2976 XL |
904 | ref vis, |
905 | ref defaultness, | |
906 | ref attrs, | |
abe05a73 | 907 | ref generics, |
3b2f2976 | 908 | ref node, |
8faf50e0 | 909 | span: _, |
3b2f2976 | 910 | } = *impl_item; |
476ff2be | 911 | |
8faf50e0 | 912 | visitor.visit_ident(ident); |
476ff2be SL |
913 | visitor.visit_vis(vis); |
914 | visitor.visit_defaultness(defaultness); | |
915 | walk_list!(visitor, visit_attribute, attrs); | |
abe05a73 | 916 | visitor.visit_generics(generics); |
476ff2be | 917 | match *node { |
32a655c1 | 918 | ImplItemKind::Const(ref ty, body) => { |
9fa01778 | 919 | visitor.visit_id(impl_item.hir_id); |
e9174d1e | 920 | visitor.visit_ty(ty); |
32a655c1 | 921 | visitor.visit_nested_body(body); |
e9174d1e | 922 | } |
476ff2be | 923 | ImplItemKind::Method(ref sig, body_id) => { |
8faf50e0 | 924 | visitor.visit_fn(FnKind::Method(impl_item.ident, |
54a0048b SL |
925 | sig, |
926 | Some(&impl_item.vis), | |
927 | &impl_item.attrs), | |
b039eaaf | 928 | &sig.decl, |
476ff2be | 929 | body_id, |
b039eaaf | 930 | impl_item.span, |
9fa01778 | 931 | impl_item.hir_id); |
e9174d1e | 932 | } |
416331ca | 933 | ImplItemKind::TyAlias(ref ty) => { |
9fa01778 | 934 | visitor.visit_id(impl_item.hir_id); |
e9174d1e SL |
935 | visitor.visit_ty(ty); |
936 | } | |
416331ca | 937 | ImplItemKind::OpaqueTy(ref bounds) => { |
9fa01778 | 938 | visitor.visit_id(impl_item.hir_id); |
8faf50e0 XL |
939 | walk_list!(visitor, visit_param_bound, bounds); |
940 | } | |
e9174d1e SL |
941 | } |
942 | } | |
943 | ||
476ff2be | 944 | pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, impl_item_ref: &'v ImplItemRef) { |
0731742a | 945 | // N.B., deliberately force a compilation error if/when new fields are added. |
8faf50e0 | 946 | let ImplItemRef { id, ident, ref kind, span: _, ref vis, ref defaultness } = *impl_item_ref; |
476ff2be | 947 | visitor.visit_nested_impl_item(id); |
8faf50e0 | 948 | visitor.visit_ident(ident); |
476ff2be SL |
949 | visitor.visit_associated_item_kind(kind); |
950 | visitor.visit_vis(vis); | |
951 | visitor.visit_defaultness(defaultness); | |
952 | } | |
953 | ||
b039eaaf | 954 | pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V, struct_definition: &'v VariantData) { |
532ac7d7 XL |
955 | if let Some(ctor_hir_id) = struct_definition.ctor_hir_id() { |
956 | visitor.visit_id(ctor_hir_id); | |
957 | } | |
b039eaaf | 958 | walk_list!(visitor, visit_struct_field, struct_definition.fields()); |
e9174d1e SL |
959 | } |
960 | ||
b039eaaf | 961 | pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V, struct_field: &'v StructField) { |
9fa01778 | 962 | visitor.visit_id(struct_field.hir_id); |
a7813a04 | 963 | visitor.visit_vis(&struct_field.vis); |
94b46f34 | 964 | visitor.visit_ident(struct_field.ident); |
54a0048b SL |
965 | visitor.visit_ty(&struct_field.ty); |
966 | walk_list!(visitor, visit_attribute, &struct_field.attrs); | |
e9174d1e SL |
967 | } |
968 | ||
969 | pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block) { | |
9fa01778 | 970 | visitor.visit_id(block.hir_id); |
b039eaaf SL |
971 | walk_list!(visitor, visit_stmt, &block.stmts); |
972 | walk_list!(visitor, visit_expr, &block.expr); | |
e9174d1e SL |
973 | } |
974 | ||
975 | pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) { | |
9fa01778 | 976 | visitor.visit_id(statement.hir_id); |
e9174d1e | 977 | match statement.node { |
9fa01778 XL |
978 | StmtKind::Local(ref local) => visitor.visit_local(local), |
979 | StmtKind::Item(item) => visitor.visit_nested_item(item), | |
980 | StmtKind::Expr(ref expression) | | |
981 | StmtKind::Semi(ref expression) => { | |
b039eaaf | 982 | visitor.visit_expr(expression) |
e9174d1e SL |
983 | } |
984 | } | |
985 | } | |
986 | ||
94b46f34 | 987 | pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonConst) { |
9fa01778 | 988 | visitor.visit_id(constant.hir_id); |
94b46f34 XL |
989 | visitor.visit_nested_body(constant.body); |
990 | } | |
991 | ||
e9174d1e | 992 | pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { |
9fa01778 | 993 | visitor.visit_id(expression.hir_id); |
8bb4bdeb | 994 | walk_list!(visitor, visit_attribute, expression.attrs.iter()); |
e9174d1e | 995 | match expression.node { |
8faf50e0 | 996 | ExprKind::Box(ref subexpression) => { |
b039eaaf | 997 | visitor.visit_expr(subexpression) |
e9174d1e | 998 | } |
8faf50e0 | 999 | ExprKind::Array(ref subexpressions) => { |
b039eaaf | 1000 | walk_list!(visitor, visit_expr, subexpressions); |
e9174d1e | 1001 | } |
8faf50e0 | 1002 | ExprKind::Repeat(ref element, ref count) => { |
b039eaaf | 1003 | visitor.visit_expr(element); |
94b46f34 | 1004 | visitor.visit_anon_const(count) |
e9174d1e | 1005 | } |
8faf50e0 | 1006 | ExprKind::Struct(ref qpath, ref fields, ref optional_base) => { |
b7449926 | 1007 | visitor.visit_qpath(qpath, expression.hir_id, expression.span); |
e9174d1e | 1008 | for field in fields { |
9fa01778 | 1009 | visitor.visit_id(field.hir_id); |
94b46f34 | 1010 | visitor.visit_ident(field.ident); |
b039eaaf | 1011 | visitor.visit_expr(&field.expr) |
e9174d1e | 1012 | } |
b039eaaf | 1013 | walk_list!(visitor, visit_expr, optional_base); |
e9174d1e | 1014 | } |
8faf50e0 | 1015 | ExprKind::Tup(ref subexpressions) => { |
b039eaaf | 1016 | walk_list!(visitor, visit_expr, subexpressions); |
e9174d1e | 1017 | } |
8faf50e0 | 1018 | ExprKind::Call(ref callee_expression, ref arguments) => { |
2c00a5a8 | 1019 | visitor.visit_expr(callee_expression); |
b039eaaf | 1020 | walk_list!(visitor, visit_expr, arguments); |
e9174d1e | 1021 | } |
8faf50e0 | 1022 | ExprKind::MethodCall(ref segment, _, ref arguments) => { |
041b39d2 | 1023 | visitor.visit_path_segment(expression.span, segment); |
b039eaaf | 1024 | walk_list!(visitor, visit_expr, arguments); |
e9174d1e | 1025 | } |
8faf50e0 | 1026 | ExprKind::Binary(_, ref left_expression, ref right_expression) => { |
b039eaaf SL |
1027 | visitor.visit_expr(left_expression); |
1028 | visitor.visit_expr(right_expression) | |
e9174d1e | 1029 | } |
8faf50e0 | 1030 | ExprKind::AddrOf(_, ref subexpression) | ExprKind::Unary(_, ref subexpression) => { |
b039eaaf | 1031 | visitor.visit_expr(subexpression) |
e9174d1e | 1032 | } |
8faf50e0 | 1033 | ExprKind::Cast(ref subexpression, ref typ) | ExprKind::Type(ref subexpression, ref typ) => { |
b039eaaf SL |
1034 | visitor.visit_expr(subexpression); |
1035 | visitor.visit_ty(typ) | |
e9174d1e | 1036 | } |
48663c56 XL |
1037 | ExprKind::DropTemps(ref subexpression) => { |
1038 | visitor.visit_expr(subexpression); | |
e9174d1e | 1039 | } |
8faf50e0 | 1040 | ExprKind::Loop(ref block, ref opt_label, _) => { |
2c00a5a8 | 1041 | walk_list!(visitor, visit_label, opt_label); |
b039eaaf | 1042 | visitor.visit_block(block); |
e9174d1e | 1043 | } |
8faf50e0 | 1044 | ExprKind::Match(ref subexpression, ref arms, _) => { |
b039eaaf SL |
1045 | visitor.visit_expr(subexpression); |
1046 | walk_list!(visitor, visit_arm, arms); | |
e9174d1e | 1047 | } |
8faf50e0 | 1048 | ExprKind::Closure(_, ref function_declaration, body, _fn_decl_span, _gen) => { |
3157f602 | 1049 | visitor.visit_fn(FnKind::Closure(&expression.attrs), |
b039eaaf SL |
1050 | function_declaration, |
1051 | body, | |
e9174d1e | 1052 | expression.span, |
9fa01778 | 1053 | expression.hir_id) |
e9174d1e | 1054 | } |
8faf50e0 | 1055 | ExprKind::Block(ref block, ref opt_label) => { |
94b46f34 XL |
1056 | walk_list!(visitor, visit_label, opt_label); |
1057 | visitor.visit_block(block); | |
1058 | } | |
8faf50e0 | 1059 | ExprKind::Assign(ref left_hand_expression, ref right_hand_expression) => { |
b039eaaf SL |
1060 | visitor.visit_expr(right_hand_expression); |
1061 | visitor.visit_expr(left_hand_expression) | |
e9174d1e | 1062 | } |
8faf50e0 | 1063 | ExprKind::AssignOp(_, ref left_expression, ref right_expression) => { |
b039eaaf | 1064 | visitor.visit_expr(right_expression); |
dc9dc135 | 1065 | visitor.visit_expr(left_expression); |
e9174d1e | 1066 | } |
8faf50e0 | 1067 | ExprKind::Field(ref subexpression, ident) => { |
b039eaaf | 1068 | visitor.visit_expr(subexpression); |
94b46f34 | 1069 | visitor.visit_ident(ident); |
e9174d1e | 1070 | } |
8faf50e0 | 1071 | ExprKind::Index(ref main_expression, ref index_expression) => { |
b039eaaf SL |
1072 | visitor.visit_expr(main_expression); |
1073 | visitor.visit_expr(index_expression) | |
e9174d1e | 1074 | } |
8faf50e0 | 1075 | ExprKind::Path(ref qpath) => { |
b7449926 | 1076 | visitor.visit_qpath(qpath, expression.hir_id, expression.span); |
e9174d1e | 1077 | } |
8faf50e0 | 1078 | ExprKind::Break(ref destination, ref opt_expr) => { |
2c00a5a8 XL |
1079 | if let Some(ref label) = destination.label { |
1080 | visitor.visit_label(label); | |
2c00a5a8 | 1081 | } |
476ff2be SL |
1082 | walk_list!(visitor, visit_expr, opt_expr); |
1083 | } | |
8faf50e0 | 1084 | ExprKind::Continue(ref destination) => { |
2c00a5a8 XL |
1085 | if let Some(ref label) = destination.label { |
1086 | visitor.visit_label(label); | |
2c00a5a8 | 1087 | } |
e9174d1e | 1088 | } |
8faf50e0 | 1089 | ExprKind::Ret(ref optional_expression) => { |
b039eaaf | 1090 | walk_list!(visitor, visit_expr, optional_expression); |
e9174d1e | 1091 | } |
8faf50e0 | 1092 | ExprKind::InlineAsm(_, ref outputs, ref inputs) => { |
b7449926 XL |
1093 | for expr in outputs.iter().chain(inputs.iter()) { |
1094 | visitor.visit_expr(expr) | |
e9174d1e SL |
1095 | } |
1096 | } | |
dc9dc135 | 1097 | ExprKind::Yield(ref subexpression, _) => { |
ea8adc8c XL |
1098 | visitor.visit_expr(subexpression); |
1099 | } | |
dc9dc135 | 1100 | ExprKind::Lit(_) | ExprKind::Err => {} |
e9174d1e | 1101 | } |
e9174d1e SL |
1102 | } |
1103 | ||
1104 | pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) { | |
dc9dc135 | 1105 | visitor.visit_id(arm.hir_id); |
b039eaaf | 1106 | walk_list!(visitor, visit_pat, &arm.pats); |
b7449926 XL |
1107 | if let Some(ref g) = arm.guard { |
1108 | match g { | |
1109 | Guard::If(ref e) => visitor.visit_expr(e), | |
1110 | } | |
1111 | } | |
b039eaaf SL |
1112 | visitor.visit_expr(&arm.body); |
1113 | walk_list!(visitor, visit_attribute, &arm.attrs); | |
e9174d1e | 1114 | } |
54a0048b | 1115 | |
a7813a04 | 1116 | pub fn walk_vis<'v, V: Visitor<'v>>(visitor: &mut V, vis: &'v Visibility) { |
532ac7d7 | 1117 | if let VisibilityKind::Restricted { ref path, hir_id } = vis.node { |
9fa01778 | 1118 | visitor.visit_id(hir_id); |
b7449926 | 1119 | visitor.visit_path(path, hir_id) |
a7813a04 XL |
1120 | } |
1121 | } | |
1122 | ||
dc9dc135 | 1123 | pub fn walk_associated_item_kind<'v, V: Visitor<'v>>(_: &mut V, _: &'v AssocItemKind) { |
476ff2be SL |
1124 | // No visitable content here: this fn exists so you can call it if |
1125 | // the right thing to do, should content be added in the future, | |
1126 | // would be to walk it. | |
1127 | } | |
1128 | ||
1129 | pub fn walk_defaultness<'v, V: Visitor<'v>>(_: &mut V, _: &'v Defaultness) { | |
1130 | // No visitable content here: this fn exists so you can call it if | |
1131 | // the right thing to do, should content be added in the future, | |
1132 | // would be to walk it. | |
1133 | } |