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