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