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