]> git.proxmox.com Git - rustc.git/blame - src/librustc_hir/intravisit.rs
New upstream version 1.44.1+dfsg1
[rustc.git] / src / librustc_hir / intravisit.rs
CommitLineData
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 34use crate::hir::*;
dfeec247
XL
35use crate::hir_id::CRATE_HIR_ID;
36use crate::itemlikevisit::{ItemLikeVisitor, ParItemLikeVisitor};
74b04a01
XL
37use rustc_ast::ast::{Attribute, Ident, Label, Name};
38use rustc_ast::walk_list;
dfeec247 39use rustc_span::Span;
dfeec247
XL
40
41pub struct DeepVisitor<'v, V> {
42 visitor: &'v mut V,
43}
44
45impl<'v, V> DeepVisitor<'v, V> {
46 pub fn new(base: &'v mut V) -> Self {
47 DeepVisitor { visitor: base }
48 }
49}
50
51impl<'v, 'hir, V> ItemLikeVisitor<'hir> for DeepVisitor<'v, V>
52where
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
68pub trait IntoVisitor<'hir> {
69 type Visitor: Visitor<'hir>;
70 fn into_visitor(&self) -> Self::Visitor;
71}
72
73pub struct ParDeepVisitor<V>(pub V);
e1599b0c 74
dfeec247
XL
75impl<'hir, V> ParItemLikeVisitor<'hir> for ParDeepVisitor<V>
76where
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 93pub 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
104impl<'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 123pub 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`.
134pub struct ErasedMap<'hir>(&'hir dyn Map<'hir>);
135
136impl<'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 161pub 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 188impl<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 226pub 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 464pub 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 470pub 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 476pub 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
483pub 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 488pub 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
498pub fn walk_ident<'v, V: Visitor<'v>>(visitor: &mut V, ident: Ident) {
499 visitor.visit_name(ident.span, ident.name);
500}
501
2c00a5a8 502pub 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 506pub 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
522pub 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 531pub 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 536pub 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(&param.pat);
dfeec247 539 walk_list!(visitor, visit_attribute, param.attrs);
416331ca
XL
540}
541
dfeec247 542pub 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 637pub 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
642pub 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
652pub 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 671pub 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
711pub 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
729pub 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
735pub 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
747pub 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
756pub 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 772pub 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 815pub 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 &param_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 835pub 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 844pub 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
859pub 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
864pub 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
893pub 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
899pub 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
906pub 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
915pub 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 929pub 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 &param_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 963pub 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 972pub 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 1016pub 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
1026pub 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 1034pub 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 1042pub 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 1048pub 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 1059pub 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 1064pub 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 1170pub 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 1182pub 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 1189pub 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
1195pub 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}