]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_middle/src/hir/map/mod.rs
New upstream version 1.71.1+dfsg1
[rustc.git] / compiler / rustc_middle / src / hir / map / mod.rs
CommitLineData
3c0e092e 1use crate::hir::{ModuleItems, Owner};
49aad941 2use crate::middle::debugger_visualizer::DebuggerVisualizerFile;
353b0b11
FG
3use crate::query::LocalCrate;
4use crate::ty::TyCtxt;
3dfed10e 5use rustc_ast as ast;
17df50a5
XL
6use rustc_data_structures::fingerprint::Fingerprint;
7use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
b7449926 8use rustc_data_structures::svh::Svh;
49aad941 9use rustc_data_structures::sync::{par_for_each_in, DynSend, DynSync};
dfeec247 10use rustc_hir::def::{DefKind, Res};
353b0b11
FG
11use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
12use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash};
c295e0f8 13use rustc_hir::intravisit::{self, Visitor};
dfeec247 14use rustc_hir::*;
49aad941 15use rustc_index::Idx;
5099ac24 16use rustc_middle::hir::nested_filter;
136023e0 17use rustc_span::def_id::StableCrateId;
136023e0 18use rustc_span::symbol::{kw, sym, Ident, Symbol};
9c376795 19use rustc_span::Span;
60c5eb7d 20use rustc_target::spec::abi::Abi;
e9174d1e 21
064997fb 22#[inline]
9ffffee4 23pub fn associated_body(node: Node<'_>) -> Option<(LocalDefId, BodyId)> {
ba9703b0
XL
24 match node {
25 Node::Item(Item {
9ffffee4 26 owner_id,
ba9703b0
XL
27 kind: ItemKind::Const(_, body) | ItemKind::Static(.., body) | ItemKind::Fn(.., body),
28 ..
29 })
30 | Node::TraitItem(TraitItem {
9ffffee4 31 owner_id,
ba9703b0
XL
32 kind:
33 TraitItemKind::Const(_, Some(body)) | TraitItemKind::Fn(_, TraitFn::Provided(body)),
34 ..
35 })
36 | Node::ImplItem(ImplItem {
9ffffee4 37 owner_id,
ba9703b0
XL
38 kind: ImplItemKind::Const(_, body) | ImplItemKind::Fn(_, body),
39 ..
9ffffee4
FG
40 }) => Some((owner_id.def_id, *body)),
41
42 Node::Expr(Expr { kind: ExprKind::Closure(Closure { def_id, body, .. }), .. }) => {
43 Some((*def_id, *body))
44 }
94b46f34 45
9ffffee4 46 Node::AnonConst(constant) => Some((constant.def_id, constant.body)),
32a655c1 47
ba9703b0 48 _ => None,
8bb4bdeb 49 }
ba9703b0 50}
8bb4bdeb 51
9c376795 52fn is_body_owner(node: Node<'_>, hir_id: HirId) -> bool {
ba9703b0 53 match associated_body(node) {
9ffffee4 54 Some((_, b)) => b.hir_id == hir_id,
ba9703b0 55 None => false,
32a655c1 56 }
1a4d82fc
JJ
57}
58
ba9703b0
XL
59#[derive(Copy, Clone)]
60pub struct Map<'hir> {
61 pub(super) tcx: TyCtxt<'hir>,
1a4d82fc
JJ
62}
63
74b04a01
XL
64/// An iterator that walks up the ancestor tree of a given `HirId`.
65/// Constructed using `tcx.hir().parent_iter(hir_id)`.
c295e0f8 66pub struct ParentHirIterator<'hir> {
e74abb32 67 current_id: HirId,
c295e0f8 68 map: Map<'hir>,
e74abb32
XL
69}
70
c295e0f8 71impl<'hir> Iterator for ParentHirIterator<'hir> {
2b03887a 72 type Item = HirId;
e74abb32
XL
73
74 fn next(&mut self) -> Option<Self::Item> {
75 if self.current_id == CRATE_HIR_ID {
76 return None;
77 }
e74abb32 78
353b0b11
FG
79 // There are nodes that do not have entries, so we need to skip them.
80 let parent_id = self.map.parent_id(self.current_id);
e74abb32 81
353b0b11
FG
82 if parent_id == self.current_id {
83 self.current_id = CRATE_HIR_ID;
84 return None;
17df50a5 85 }
353b0b11
FG
86
87 self.current_id = parent_id;
88 return Some(parent_id);
17df50a5
XL
89 }
90}
91
92/// An iterator that walks up the ancestor tree of a given `HirId`.
93/// Constructed using `tcx.hir().parent_owner_iter(hir_id)`.
c295e0f8 94pub struct ParentOwnerIterator<'hir> {
17df50a5 95 current_id: HirId,
c295e0f8 96 map: Map<'hir>,
17df50a5
XL
97}
98
c295e0f8 99impl<'hir> Iterator for ParentOwnerIterator<'hir> {
2b03887a 100 type Item = (OwnerId, OwnerNode<'hir>);
17df50a5
XL
101
102 fn next(&mut self) -> Option<Self::Item> {
103 if self.current_id.local_id.index() != 0 {
104 self.current_id.local_id = ItemLocalId::new(0);
94222f64 105 if let Some(node) = self.map.tcx.hir_owner(self.current_id.owner) {
5099ac24 106 return Some((self.current_id.owner, node.node));
17df50a5
XL
107 }
108 }
109 if self.current_id == CRATE_HIR_ID {
110 return None;
111 }
112 loop {
113 // There are nodes that do not have entries, so we need to skip them.
2b03887a 114 let parent_id = self.map.def_key(self.current_id.owner.def_id).parent;
17df50a5 115
2b03887a 116 let parent_id = parent_id.map_or(CRATE_OWNER_ID, |local_def_index| {
17df50a5
XL
117 let def_id = LocalDefId { local_def_index };
118 self.map.local_def_id_to_hir_id(def_id).owner
119 });
2b03887a 120 self.current_id = HirId::make_owner(parent_id.def_id);
17df50a5
XL
121
122 // If this `HirId` doesn't have an entry, skip it and look for its `parent_id`.
94222f64 123 if let Some(node) = self.map.tcx.hir_owner(self.current_id.owner) {
5099ac24 124 return Some((self.current_id.owner, node.node));
e74abb32 125 }
e74abb32
XL
126 }
127 }
128}
129
32a655c1 130impl<'hir> Map<'hir> {
f2b60f7d 131 #[inline]
5099ac24 132 pub fn krate(self) -> &'hir Crate<'hir> {
17df50a5 133 self.tcx.hir_crate(())
74b04a01
XL
134 }
135
f2b60f7d 136 #[inline]
5099ac24 137 pub fn root_module(self) -> &'hir Mod<'hir> {
2b03887a 138 match self.tcx.hir_owner(CRATE_OWNER_ID).map(|o| o.node) {
c295e0f8
XL
139 Some(OwnerNode::Crate(item)) => item,
140 _ => bug!(),
141 }
142 }
143
f2b60f7d 144 #[inline]
04454e1e
FG
145 pub fn items(self) -> impl Iterator<Item = ItemId> + 'hir {
146 self.tcx.hir_crate_items(()).items.iter().copied()
147 }
148
f2b60f7d 149 #[inline]
923072b8
FG
150 pub fn module_items(self, module: LocalDefId) -> impl Iterator<Item = ItemId> + 'hir {
151 self.tcx.hir_module_items(module).items()
152 }
153
5099ac24 154 pub fn def_key(self, def_id: LocalDefId) -> DefKey {
136023e0 155 // Accessing the DefKey is ok, since it is part of DefPathHash.
923072b8 156 self.tcx.definitions_untracked().def_key(def_id)
b039eaaf
SL
157 }
158
5099ac24 159 pub fn def_path(self, def_id: LocalDefId) -> DefPath {
136023e0 160 // Accessing the DefPath is ok, since it is part of DefPathHash.
923072b8 161 self.tcx.definitions_untracked().def_path(def_id)
136023e0
XL
162 }
163
164 #[inline]
165 pub fn def_path_hash(self, def_id: LocalDefId) -> DefPathHash {
166 // Accessing the DefPathHash is ok, it is incr. comp. stable.
923072b8 167 self.tcx.definitions_untracked().def_path_hash(def_id)
b039eaaf
SL
168 }
169
abe05a73 170 #[inline]
5099ac24
FG
171 pub fn local_def_id_to_hir_id(self, def_id: LocalDefId) -> HirId {
172 self.tcx.local_def_id_to_hir_id(def_id)
ba9703b0
XL
173 }
174
064997fb
FG
175 /// Do not call this function directly. The query should be called.
176 pub(super) fn opt_def_kind(self, local_def_id: LocalDefId) -> Option<DefKind> {
f9f354fc 177 let hir_id = self.local_def_id_to_hir_id(local_def_id);
353b0b11
FG
178 let node = match self.find(hir_id) {
179 Some(node) => node,
180 None => match self.def_key(local_def_id).disambiguated_data.data {
181 // FIXME: Some anonymous constants do not have corresponding HIR nodes,
182 // so many local queries will panic on their def ids. `None` is currently
183 // returned here instead of `DefKind::{Anon,Inline}Const` to avoid such panics.
184 // Ideally all def ids should have `DefKind`s, we need to create the missing
185 // HIR nodes or feed relevant query results to achieve that.
186 DefPathData::AnonConst => return None,
187 _ => bug!("no HIR node for def id {local_def_id:?}"),
188 },
189 };
190 let def_kind = match node {
60c5eb7d 191 Node::Item(item) => match item.kind {
5e7ed085 192 ItemKind::Static(_, mt, _) => DefKind::Static(mt),
60c5eb7d
XL
193 ItemKind::Const(..) => DefKind::Const,
194 ItemKind::Fn(..) => DefKind::Fn,
5e7ed085 195 ItemKind::Macro(_, macro_kind) => DefKind::Macro(macro_kind),
60c5eb7d 196 ItemKind::Mod(..) => DefKind::Mod,
f2b60f7d 197 ItemKind::OpaqueTy(ref opaque) => {
353b0b11 198 if opaque.in_trait && !self.tcx.lower_impl_trait_in_trait_to_assoc_ty() {
f2b60f7d
FG
199 DefKind::ImplTraitPlaceholder
200 } else {
201 DefKind::OpaqueTy
202 }
203 }
60c5eb7d
XL
204 ItemKind::TyAlias(..) => DefKind::TyAlias,
205 ItemKind::Enum(..) => DefKind::Enum,
206 ItemKind::Struct(..) => DefKind::Struct,
207 ItemKind::Union(..) => DefKind::Union,
208 ItemKind::Trait(..) => DefKind::Trait,
209 ItemKind::TraitAlias(..) => DefKind::TraitAlias,
f9f354fc
XL
210 ItemKind::ExternCrate(_) => DefKind::ExternCrate,
211 ItemKind::Use(..) => DefKind::Use,
fc512014 212 ItemKind::ForeignMod { .. } => DefKind::ForeignMod,
f9f354fc 213 ItemKind::GlobalAsm(..) => DefKind::GlobalAsm,
9ffffee4 214 ItemKind::Impl(impl_) => DefKind::Impl { of_trait: impl_.of_trait.is_some() },
60c5eb7d
XL
215 },
216 Node::ForeignItem(item) => match item.kind {
217 ForeignItemKind::Fn(..) => DefKind::Fn,
5e7ed085 218 ForeignItemKind::Static(_, mt) => DefKind::Static(mt),
60c5eb7d
XL
219 ForeignItemKind::Type => DefKind::ForeignTy,
220 },
221 Node::TraitItem(item) => match item.kind {
222 TraitItemKind::Const(..) => DefKind::AssocConst,
ba9703b0 223 TraitItemKind::Fn(..) => DefKind::AssocFn,
60c5eb7d
XL
224 TraitItemKind::Type(..) => DefKind::AssocTy,
225 },
226 Node::ImplItem(item) => match item.kind {
227 ImplItemKind::Const(..) => DefKind::AssocConst,
ba9703b0 228 ImplItemKind::Fn(..) => DefKind::AssocFn,
2b03887a 229 ImplItemKind::Type(..) => DefKind::AssocTy,
60c5eb7d 230 },
48663c56 231 Node::Variant(_) => DefKind::Variant,
532ac7d7 232 Node::Ctor(variant_data) => {
9c376795 233 let ctor_of = match self.find_parent(hir_id) {
532ac7d7
XL
234 Some(Node::Item(..)) => def::CtorOf::Struct,
235 Some(Node::Variant(..)) => def::CtorOf::Variant,
236 _ => unreachable!(),
237 };
487cf647
FG
238 match variant_data.ctor_kind() {
239 Some(kind) => DefKind::Ctor(ctor_of, kind),
240 None => bug!("constructor node without a constructor"),
241 }
9fa01778 242 }
3c0e092e 243 Node::AnonConst(_) => {
9c376795 244 let inline = match self.find_parent(hir_id) {
3c0e092e
XL
245 Some(Node::Expr(&Expr {
246 kind: ExprKind::ConstBlock(ref anon_const), ..
247 })) if anon_const.hir_id == hir_id => true,
248 _ => false,
249 };
250 if inline { DefKind::InlineConst } else { DefKind::AnonConst }
251 }
f9f354fc
XL
252 Node::Field(_) => DefKind::Field,
253 Node::Expr(expr) => match expr.kind {
064997fb
FG
254 ExprKind::Closure(Closure { movability: None, .. }) => DefKind::Closure,
255 ExprKind::Closure(Closure { movability: Some(_), .. }) => DefKind::Generator,
f9f354fc
XL
256 _ => bug!("def_kind: unsupported node: {}", self.node_to_string(hir_id)),
257 },
f9f354fc
XL
258 Node::GenericParam(param) => match param.kind {
259 GenericParamKind::Lifetime { .. } => DefKind::LifetimeParam,
260 GenericParamKind::Type { .. } => DefKind::TyParam,
261 GenericParamKind::Const { .. } => DefKind::ConstParam,
262 },
5869c6ff 263 Node::Crate(_) => DefKind::Mod,
f9f354fc 264 Node::Stmt(_)
60c5eb7d
XL
265 | Node::PathSegment(_)
266 | Node::Ty(_)
923072b8 267 | Node::TypeBinding(_)
94222f64 268 | Node::Infer(_)
60c5eb7d
XL
269 | Node::TraitRef(_)
270 | Node::Pat(_)
f2b60f7d
FG
271 | Node::PatField(_)
272 | Node::ExprField(_)
60c5eb7d
XL
273 | Node::Local(_)
274 | Node::Param(_)
275 | Node::Arm(_)
276 | Node::Lifetime(_)
353b0b11
FG
277 | Node::Block(_) => span_bug!(
278 self.span(hir_id),
279 "unexpected node with def id {local_def_id:?}: {node:?}"
280 ),
5869c6ff
XL
281 };
282 Some(def_kind)
283 }
284
f2b60f7d
FG
285 /// Finds the id of the parent node to this one.
286 ///
287 /// If calling repeatedly and iterating over parents, prefer [`Map::parent_iter`].
9c376795 288 pub fn opt_parent_id(self, id: HirId) -> Option<HirId> {
ba9703b0 289 if id.local_id == ItemLocalId::from_u32(0) {
17df50a5 290 Some(self.tcx.hir_owner_parent(id.owner))
ba9703b0 291 } else {
5099ac24 292 let owner = self.tcx.hir_owner_nodes(id.owner).as_owner()?;
17df50a5
XL
293 let node = owner.nodes[id.local_id].as_ref()?;
294 let hir_id = HirId { owner: id.owner, local_id: node.parent };
f2b60f7d
FG
295 // HIR indexing should have checked that.
296 debug_assert_ne!(id.local_id, node.parent);
17df50a5
XL
297 Some(hir_id)
298 }
299 }
300
9c376795
FG
301 #[track_caller]
302 pub fn parent_id(self, hir_id: HirId) -> HirId {
303 self.opt_parent_id(hir_id)
9ffffee4 304 .unwrap_or_else(|| bug!("No parent for node {}", self.node_to_string(hir_id)))
17df50a5
XL
305 }
306
9c376795
FG
307 pub fn get_parent(self, hir_id: HirId) -> Node<'hir> {
308 self.get(self.parent_id(hir_id))
309 }
310
311 pub fn find_parent(self, hir_id: HirId) -> Option<Node<'hir>> {
312 self.find(self.opt_parent_id(hir_id)?)
313 }
314
17df50a5 315 /// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
5099ac24 316 pub fn find(self, id: HirId) -> Option<Node<'hir>> {
17df50a5
XL
317 if id.local_id == ItemLocalId::from_u32(0) {
318 let owner = self.tcx.hir_owner(id.owner)?;
94222f64 319 Some(owner.node.into())
17df50a5 320 } else {
5099ac24 321 let owner = self.tcx.hir_owner_nodes(id.owner).as_owner()?;
17df50a5
XL
322 let node = owner.nodes[id.local_id].as_ref()?;
323 Some(node.node)
ba9703b0 324 }
1a4d82fc
JJ
325 }
326
5099ac24
FG
327 /// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
328 #[inline]
329 pub fn find_by_def_id(self, id: LocalDefId) -> Option<Node<'hir>> {
353b0b11 330 self.find(self.tcx.opt_local_def_id_to_hir_id(id)?)
5099ac24
FG
331 }
332
17df50a5 333 /// Retrieves the `Node` corresponding to `id`, panicking if it cannot be found.
9c376795 334 #[track_caller]
5099ac24 335 pub fn get(self, id: HirId) -> Node<'hir> {
17df50a5
XL
336 self.find(id).unwrap_or_else(|| bug!("couldn't find hir id {} in the HIR map", id))
337 }
338
5099ac24
FG
339 /// Retrieves the `Node` corresponding to `id`, panicking if it cannot be found.
340 #[inline]
9c376795 341 #[track_caller]
5099ac24
FG
342 pub fn get_by_def_id(self, id: LocalDefId) -> Node<'hir> {
343 self.find_by_def_id(id).unwrap_or_else(|| bug!("couldn't find {:?} in the HIR map", id))
344 }
345
346 pub fn get_if_local(self, id: DefId) -> Option<Node<'hir>> {
353b0b11 347 id.as_local().and_then(|id| self.find(self.tcx.opt_local_def_id_to_hir_id(id)?))
17df50a5
XL
348 }
349
5099ac24 350 pub fn get_generics(self, id: LocalDefId) -> Option<&'hir Generics<'hir>> {
2b03887a 351 let node = self.tcx.hir_owner(OwnerId { def_id: id })?;
923072b8 352 node.node.generics()
ba9703b0 353 }
dfeec247 354
487cf647
FG
355 pub fn owner(self, id: OwnerId) -> OwnerNode<'hir> {
356 self.tcx.hir_owner(id).unwrap_or_else(|| bug!("expected owner for {:?}", id)).node
357 }
358
5099ac24 359 pub fn item(self, id: ItemId) -> &'hir Item<'hir> {
2b03887a 360 self.tcx.hir_owner(id.owner_id).unwrap().node.expect_item()
dfeec247
XL
361 }
362
5099ac24 363 pub fn trait_item(self, id: TraitItemId) -> &'hir TraitItem<'hir> {
2b03887a 364 self.tcx.hir_owner(id.owner_id).unwrap().node.expect_trait_item()
32a655c1
SL
365 }
366
5099ac24 367 pub fn impl_item(self, id: ImplItemId) -> &'hir ImplItem<'hir> {
2b03887a 368 self.tcx.hir_owner(id.owner_id).unwrap().node.expect_impl_item()
476ff2be
SL
369 }
370
5099ac24 371 pub fn foreign_item(self, id: ForeignItemId) -> &'hir ForeignItem<'hir> {
2b03887a 372 self.tcx.hir_owner(id.owner_id).unwrap().node.expect_foreign_item()
fc512014
XL
373 }
374
5099ac24 375 pub fn body(self, id: BodyId) -> &'hir Body<'hir> {
3c0e092e 376 self.tcx.hir_owner_nodes(id.hir_id.owner).unwrap().bodies[&id.hir_id.local_id]
32a655c1
SL
377 }
378
9c376795 379 #[track_caller]
5099ac24 380 pub fn fn_decl_by_hir_id(self, hir_id: HirId) -> Option<&'hir FnDecl<'hir>> {
ba9703b0 381 if let Some(node) = self.find(hir_id) {
f2b60f7d 382 node.fn_decl()
48663c56 383 } else {
ba9703b0 384 bug!("no node for hir_id `{}`", hir_id)
48663c56 385 }
9fa01778
XL
386 }
387
9c376795 388 #[track_caller]
5099ac24 389 pub fn fn_sig_by_hir_id(self, hir_id: HirId) -> Option<&'hir FnSig<'hir>> {
ba9703b0 390 if let Some(node) = self.find(hir_id) {
f2b60f7d 391 node.fn_sig()
60c5eb7d 392 } else {
ba9703b0 393 bug!("no node for hir_id `{}`", hir_id)
60c5eb7d
XL
394 }
395 }
396
9c376795 397 #[track_caller]
064997fb 398 pub fn enclosing_body_owner(self, hir_id: HirId) -> LocalDefId {
2b03887a 399 for (_, node) in self.parent_iter(hir_id) {
9ffffee4
FG
400 if let Some((def_id, _)) = associated_body(node) {
401 return def_id;
f035d41b
XL
402 }
403 }
404
405 bug!("no `enclosing_body_owner` for hir_id `{}`", hir_id);
406 }
407
dc9dc135 408 /// Returns the `HirId` that corresponds to the definition of
0731742a 409 /// which this is the body of, i.e., a `fn`, `const` or `static`
94b46f34 410 /// item (possibly associated), a closure, or a `hir::AnonConst`.
5099ac24 411 pub fn body_owner(self, BodyId { hir_id }: BodyId) -> HirId {
9c376795 412 let parent = self.parent_id(hir_id);
49aad941 413 assert!(self.find(parent).is_some_and(|n| is_body_owner(n, hir_id)), "{hir_id:?}");
dc9dc135 414 parent
32a655c1
SL
415 }
416
9ffffee4
FG
417 pub fn body_owner_def_id(self, BodyId { hir_id }: BodyId) -> LocalDefId {
418 let parent = self.parent_id(hir_id);
419 associated_body(self.get(parent)).unwrap().0
32a655c1
SL
420 }
421
064997fb 422 /// Given a `LocalDefId`, returns the `BodyId` associated with it,
7cac9316 423 /// if the node is a body owner, otherwise returns `None`.
064997fb 424 pub fn maybe_body_owned_by(self, id: LocalDefId) -> Option<BodyId> {
9ffffee4
FG
425 let node = self.find_by_def_id(id)?;
426 let (_, body_id) = associated_body(node)?;
427 Some(body_id)
cc61c64b
XL
428 }
429
7cac9316 430 /// Given a body owner's id, returns the `BodyId` associated with it.
9c376795 431 #[track_caller]
064997fb 432 pub fn body_owned_by(self, id: LocalDefId) -> BodyId {
dc9dc135 433 self.maybe_body_owned_by(id).unwrap_or_else(|| {
064997fb 434 let hir_id = self.local_def_id_to_hir_id(id);
60c5eb7d 435 span_bug!(
064997fb 436 self.span(hir_id),
60c5eb7d 437 "body_owned_by: {} has no associated body",
064997fb 438 self.node_to_string(hir_id)
60c5eb7d 439 );
7cac9316
XL
440 })
441 }
442
5099ac24 443 pub fn body_param_names(self, id: BodyId) -> impl Iterator<Item = Ident> + 'hir {
f035d41b
XL
444 self.body(id).params.iter().map(|arg| match arg.pat.kind {
445 PatKind::Binding(_, _, ident, _) => ident,
3c0e092e 446 _ => Ident::empty(),
f035d41b
XL
447 })
448 }
449
f9f354fc
XL
450 /// Returns the `BodyOwnerKind` of this `LocalDefId`.
451 ///
452 /// Panics if `LocalDefId` does not have an associated body.
5e7ed085
FG
453 pub fn body_owner_kind(self, def_id: LocalDefId) -> BodyOwnerKind {
454 match self.tcx.def_kind(def_id) {
455 DefKind::Const | DefKind::AssocConst | DefKind::InlineConst | DefKind::AnonConst => {
456 BodyOwnerKind::Const
457 }
458 DefKind::Ctor(..) | DefKind::Fn | DefKind::AssocFn => BodyOwnerKind::Fn,
459 DefKind::Closure | DefKind::Generator => BodyOwnerKind::Closure,
460 DefKind::Static(mt) => BodyOwnerKind::Static(mt),
461 dk => bug!("{:?} is not a body node: {:?}", def_id, dk),
abe05a73
XL
462 }
463 }
464
f9f354fc
XL
465 /// Returns the `ConstContext` of the body associated with this `LocalDefId`.
466 ///
467 /// Panics if `LocalDefId` does not have an associated body.
136023e0
XL
468 ///
469 /// This should only be used for determining the context of a body, a return
a2a8927a
XL
470 /// value of `Some` does not always suggest that the owner of the body is `const`,
471 /// just that it has to be checked as if it were.
5e7ed085
FG
472 pub fn body_const_context(self, def_id: LocalDefId) -> Option<ConstContext> {
473 let ccx = match self.body_owner_kind(def_id) {
f9f354fc
XL
474 BodyOwnerKind::Const => ConstContext::Const,
475 BodyOwnerKind::Static(mt) => ConstContext::Static(mt),
476
5e7ed085 477 BodyOwnerKind::Fn if self.tcx.is_constructor(def_id.to_def_id()) => return None,
9c376795
FG
478 BodyOwnerKind::Fn | BodyOwnerKind::Closure
479 if self.tcx.is_const_fn_raw(def_id.to_def_id()) =>
480 {
5e7ed085
FG
481 ConstContext::ConstFn
482 }
923072b8 483 BodyOwnerKind::Fn if self.tcx.is_const_default_method(def_id.to_def_id()) => {
136023e0
XL
484 ConstContext::ConstFn
485 }
f9f354fc
XL
486 BodyOwnerKind::Fn | BodyOwnerKind::Closure => return None,
487 };
488
489 Some(ccx)
490 }
491
c295e0f8
XL
492 /// Returns an iterator of the `DefId`s for all body-owners in this
493 /// crate. If you would prefer to iterate over the bodies
494 /// themselves, you can do `self.hir().krate().body_ids.iter()`.
f2b60f7d 495 #[inline]
c295e0f8 496 pub fn body_owners(self) -> impl Iterator<Item = LocalDefId> + 'hir {
064997fb 497 self.tcx.hir_crate_items(()).body_owners.iter().copied()
c295e0f8
XL
498 }
499
f2b60f7d 500 #[inline]
49aad941 501 pub fn par_body_owners(self, f: impl Fn(LocalDefId) + DynSend + DynSync) {
064997fb 502 par_for_each_in(&self.tcx.hir_crate_items(()).body_owners[..], |&def_id| f(def_id));
c295e0f8
XL
503 }
504
04454e1e
FG
505 pub fn ty_param_owner(self, def_id: LocalDefId) -> LocalDefId {
506 let def_kind = self.tcx.def_kind(def_id);
507 match def_kind {
508 DefKind::Trait | DefKind::TraitAlias => def_id,
f2b60f7d
FG
509 DefKind::LifetimeParam | DefKind::TyParam | DefKind::ConstParam => {
510 self.tcx.local_parent(def_id)
511 }
04454e1e 512 _ => bug!("ty_param_owner: {:?} is a {:?} not a type parameter", def_id, def_kind),
8bb4bdeb
XL
513 }
514 }
515
04454e1e
FG
516 pub fn ty_param_name(self, def_id: LocalDefId) -> Symbol {
517 let def_kind = self.tcx.def_kind(def_id);
518 match def_kind {
519 DefKind::Trait | DefKind::TraitAlias => kw::SelfUpper,
f2b60f7d
FG
520 DefKind::LifetimeParam | DefKind::TyParam | DefKind::ConstParam => {
521 self.tcx.item_name(def_id.to_def_id())
522 }
04454e1e 523 _ => bug!("ty_param_name: {:?} is a {:?} not a type parameter", def_id, def_kind),
8bb4bdeb
XL
524 }
525 }
526
5099ac24 527 pub fn trait_impls(self, trait_did: DefId) -> &'hir [LocalDefId] {
17df50a5 528 self.tcx.all_local_trait_impls(()).get(&trait_did).map_or(&[], |xs| &xs[..])
8bb4bdeb
XL
529 }
530
9fa01778 531 /// Gets the attributes on the crate. This is preferable to
54a0048b
SL
532 /// invoking `krate.attrs` because it registers a tighter
533 /// dep-graph access.
5099ac24 534 pub fn krate_attrs(self) -> &'hir [ast::Attribute] {
6a06907d 535 self.attrs(CRATE_HIR_ID)
54a0048b
SL
536 }
537
5e7ed085
FG
538 pub fn rustc_coherence_is_core(self) -> bool {
539 self.krate_attrs().iter().any(|attr| attr.has_name(sym::rustc_coherence_is_core))
540 }
541
5099ac24 542 pub fn get_module(self, module: LocalDefId) -> (&'hir Mod<'hir>, Span, HirId) {
94222f64 543 let hir_id = HirId::make_owner(module);
2b03887a 544 match self.tcx.hir_owner(hir_id.owner).map(|o| o.node) {
94222f64
XL
545 Some(OwnerNode::Item(&Item { span, kind: ItemKind::Mod(ref m), .. })) => {
546 (m, span, hir_id)
547 }
04454e1e 548 Some(OwnerNode::Crate(item)) => (item, item.spans.inner_span, hir_id),
e1599b0c 549 node => panic!("not a module: {:?}", node),
9fa01778
XL
550 }
551 }
552
064997fb 553 /// Walks the contents of the local crate. See also `visit_all_item_likes_in_crate`.
c295e0f8
XL
554 pub fn walk_toplevel_module(self, visitor: &mut impl Visitor<'hir>) {
555 let (top_mod, span, hir_id) = self.get_module(CRATE_DEF_ID);
556 visitor.visit_mod(top_mod, span, hir_id);
557 }
558
559 /// Walks the attributes in a crate.
560 pub fn walk_attributes(self, visitor: &mut impl Visitor<'hir>) {
561 let krate = self.krate();
923072b8 562 for info in krate.owners.iter() {
5099ac24 563 if let MaybeOwner::Owner(info) = info {
923072b8 564 for attrs in info.attrs.map.values() {
3c0e092e 565 for a in *attrs {
923072b8 566 visitor.visit_attribute(a)
3c0e092e
XL
567 }
568 }
c295e0f8
XL
569 }
570 }
571 }
572
064997fb
FG
573 /// Visits all item-likes in the crate in some deterministic (but unspecified) order. If you
574 /// need to process every item-like, and don't care about visiting nested items in a particular
9c376795 575 /// order then this method is the best choice. If you do care about this nesting, you should
064997fb
FG
576 /// use the `tcx.hir().walk_toplevel_module`.
577 ///
9c376795 578 /// Note that this function will access HIR for all the item-likes in the crate. If you only
064997fb
FG
579 /// need to access some of them, it is usually better to manually loop on the iterators
580 /// provided by `tcx.hir_crate_items(())`.
c295e0f8 581 ///
923072b8 582 /// Please see the notes in `intravisit.rs` for more information.
064997fb 583 pub fn visit_all_item_likes_in_crate<V>(self, visitor: &mut V)
c295e0f8 584 where
923072b8 585 V: Visitor<'hir>,
c295e0f8 586 {
064997fb
FG
587 let krate = self.tcx.hir_crate_items(());
588
589 for id in krate.items() {
590 visitor.visit_item(self.item(id));
c295e0f8 591 }
c295e0f8 592
064997fb
FG
593 for id in krate.trait_items() {
594 visitor.visit_trait_item(self.trait_item(id));
595 }
596
597 for id in krate.impl_items() {
598 visitor.visit_impl_item(self.impl_item(id));
599 }
600
601 for id in krate.foreign_items() {
602 visitor.visit_foreign_item(self.foreign_item(id));
603 }
c295e0f8
XL
604 }
605
064997fb
FG
606 /// This method is the equivalent of `visit_all_item_likes_in_crate` but restricted to
607 /// item-likes in a single module.
608 pub fn visit_item_likes_in_module<V>(self, module: LocalDefId, visitor: &mut V)
60c5eb7d 609 where
923072b8 610 V: Visitor<'hir>,
0731742a 611 {
f035d41b 612 let module = self.tcx.hir_module_items(module);
0731742a 613
064997fb
FG
614 for id in module.items() {
615 visitor.visit_item(self.item(id));
0731742a
XL
616 }
617
064997fb
FG
618 for id in module.trait_items() {
619 visitor.visit_trait_item(self.trait_item(id));
0731742a
XL
620 }
621
064997fb
FG
622 for id in module.impl_items() {
623 visitor.visit_impl_item(self.impl_item(id));
0731742a 624 }
fc512014 625
064997fb
FG
626 for id in module.foreign_items() {
627 visitor.visit_foreign_item(self.foreign_item(id));
fc512014 628 }
0731742a
XL
629 }
630
923072b8 631 pub fn for_each_module(self, mut f: impl FnMut(LocalDefId)) {
04454e1e
FG
632 let crate_items = self.tcx.hir_crate_items(());
633 for module in crate_items.submodules.iter() {
2b03887a 634 f(module.def_id)
c295e0f8
XL
635 }
636 }
637
c295e0f8 638 #[inline]
49aad941 639 pub fn par_for_each_module(self, f: impl Fn(LocalDefId) + DynSend + DynSync) {
f2b60f7d 640 let crate_items = self.tcx.hir_crate_items(());
2b03887a 641 par_for_each_in(&crate_items.submodules[..], |module| f(module.def_id))
c295e0f8
XL
642 }
643
74b04a01 644 /// Returns an iterator for the nodes in the ancestor tree of the `current_id`
9c376795 645 /// until the crate root is reached. Prefer this over your own loop using `parent_id`.
f2b60f7d 646 #[inline]
2b03887a 647 pub fn parent_id_iter(self, current_id: HirId) -> impl Iterator<Item = HirId> + 'hir {
74b04a01
XL
648 ParentHirIterator { current_id, map: self }
649 }
650
2b03887a 651 /// Returns an iterator for the nodes in the ancestor tree of the `current_id`
9c376795 652 /// until the crate root is reached. Prefer this over your own loop using `parent_id`.
2b03887a
FG
653 #[inline]
654 pub fn parent_iter(self, current_id: HirId) -> impl Iterator<Item = (HirId, Node<'hir>)> {
655 self.parent_id_iter(current_id).filter_map(move |id| Some((id, self.find(id)?)))
656 }
657
17df50a5 658 /// Returns an iterator for the nodes in the ancestor tree of the `current_id`
9c376795 659 /// until the crate root is reached. Prefer this over your own loop using `parent_id`.
f2b60f7d 660 #[inline]
c295e0f8 661 pub fn parent_owner_iter(self, current_id: HirId) -> ParentOwnerIterator<'hir> {
17df50a5
XL
662 ParentOwnerIterator { current_id, map: self }
663 }
664
5869c6ff 665 /// Checks if the node is left-hand side of an assignment.
5099ac24 666 pub fn is_lhs(self, id: HirId) -> bool {
9c376795 667 match self.find_parent(id) {
5869c6ff
XL
668 Some(Node::Expr(expr)) => match expr.kind {
669 ExprKind::Assign(lhs, _rhs, _span) => lhs.hir_id == id,
670 _ => false,
671 },
672 _ => false,
673 }
674 }
675
e1599b0c
XL
676 /// Whether the expression pointed at by `hir_id` belongs to a `const` evaluation context.
677 /// Used exclusively for diagnostics, to avoid suggestion function calls.
5099ac24 678 pub fn is_inside_const_context(self, hir_id: HirId) -> bool {
064997fb 679 self.body_const_context(self.enclosing_body_owner(hir_id)).is_some()
e1599b0c
XL
680 }
681
dc9dc135 682 /// Retrieves the `HirId` for `id`'s enclosing method, unless there's a
3b2f2976 683 /// `while` or `loop` before reaching it, as block tail returns are not
041b39d2
XL
684 /// available in them.
685 ///
686 /// ```
687 /// fn foo(x: usize) -> bool {
688 /// if x == 1 {
e1599b0c 689 /// true // If `get_return_block` gets passed the `id` corresponding
dc9dc135 690 /// } else { // to this, it will return `foo`'s `HirId`.
041b39d2
XL
691 /// false
692 /// }
693 /// }
694 /// ```
695 ///
04454e1e 696 /// ```compile_fail,E0308
041b39d2
XL
697 /// fn foo(x: usize) -> bool {
698 /// loop {
e1599b0c 699 /// true // If `get_return_block` gets passed the `id` corresponding
041b39d2
XL
700 /// } // to this, it will return `None`.
701 /// false
702 /// }
703 /// ```
5099ac24 704 pub fn get_return_block(self, id: HirId) -> Option<HirId> {
74b04a01 705 let mut iter = self.parent_iter(id).peekable();
e74abb32 706 let mut ignore_tail = false;
9c376795
FG
707 if let Some(Node::Expr(Expr { kind: ExprKind::Ret(_), .. })) = self.find(id) {
708 // When dealing with `return` statements, we don't care about climbing only tail
709 // expressions.
710 ignore_tail = true;
e74abb32
XL
711 }
712 while let Some((hir_id, node)) = iter.next() {
713 if let (Some((_, next_node)), false) = (iter.peek(), ignore_tail) {
714 match next_node {
715 Node::Block(Block { expr: None, .. }) => return None,
ba9703b0
XL
716 // The current node is not the tail expression of its parent.
717 Node::Block(Block { expr: Some(e), .. }) if hir_id != e.hir_id => return None,
e74abb32
XL
718 _ => {}
719 }
720 }
721 match node {
60c5eb7d
XL
722 Node::Item(_)
723 | Node::ForeignItem(_)
724 | Node::TraitItem(_)
923072b8 725 | Node::Expr(Expr { kind: ExprKind::Closure { .. }, .. })
60c5eb7d 726 | Node::ImplItem(_) => return Some(hir_id),
ba9703b0
XL
727 // Ignore `return`s on the first iteration
728 Node::Expr(Expr { kind: ExprKind::Loop(..) | ExprKind::Ret(..), .. })
729 | Node::Local(_) => {
730 return None;
041b39d2 731 }
e74abb32 732 _ => {}
041b39d2 733 }
e74abb32
XL
734 }
735 None
041b39d2
XL
736 }
737
2b03887a 738 /// Retrieves the `OwnerId` for `id`'s parent item, or `id` itself if no
c1a9b12d 739 /// parent item is in this map. The "parent item" is the closest parent node
94b46f34 740 /// in the HIR which is recorded by the map and is an item, either an item
c1a9b12d 741 /// in a module, trait, or impl.
2b03887a 742 pub fn get_parent_item(self, hir_id: HirId) -> OwnerId {
5099ac24
FG
743 if let Some((def_id, _node)) = self.parent_owner_iter(hir_id).next() {
744 def_id
94222f64 745 } else {
2b03887a 746 CRATE_OWNER_ID
c1a9b12d
SL
747 }
748 }
749
2b03887a 750 /// Returns the `OwnerId` of `id`'s nearest module parent, or `id` itself if no
0bf4aa26 751 /// module parent is in this map.
2b03887a 752 pub(super) fn get_module_parent_node(self, hir_id: HirId) -> OwnerId {
5099ac24 753 for (def_id, node) in self.parent_owner_iter(hir_id) {
94222f64 754 if let OwnerNode::Item(&Item { kind: ItemKind::Mod(_), .. }) = node {
5099ac24 755 return def_id;
e74abb32
XL
756 }
757 }
2b03887a 758 CRATE_OWNER_ID
e74abb32
XL
759 }
760
5869c6ff
XL
761 /// When on an if expression, a match arm tail expression or a match arm, give back
762 /// the enclosing `if` or `match` expression.
e74abb32 763 ///
5869c6ff 764 /// Used by error reporting when there's a type error in an if or match arm caused by the
e74abb32 765 /// expression needing to be unit.
5099ac24 766 pub fn get_if_cause(self, hir_id: HirId) -> Option<&'hir Expr<'hir>> {
74b04a01 767 for (_, node) in self.parent_iter(hir_id) {
e74abb32 768 match node {
ba9703b0
XL
769 Node::Item(_)
770 | Node::ForeignItem(_)
771 | Node::TraitItem(_)
772 | Node::ImplItem(_)
773 | Node::Stmt(Stmt { kind: StmtKind::Local(_), .. }) => break,
5869c6ff
XL
774 Node::Expr(expr @ Expr { kind: ExprKind::If(..) | ExprKind::Match(..), .. }) => {
775 return Some(expr);
776 }
e74abb32
XL
777 _ => {}
778 }
0bf4aa26 779 }
e74abb32 780 None
54a0048b
SL
781 }
782
dc9dc135 783 /// Returns the nearest enclosing scope. A scope is roughly an item or block.
5099ac24 784 pub fn get_enclosing_scope(self, hir_id: HirId) -> Option<HirId> {
74b04a01 785 for (hir_id, node) in self.parent_iter(hir_id) {
ba9703b0
XL
786 if let Node::Item(Item {
787 kind:
60c5eb7d 788 ItemKind::Fn(..)
f035d41b
XL
789 | ItemKind::Const(..)
790 | ItemKind::Static(..)
60c5eb7d
XL
791 | ItemKind::Mod(..)
792 | ItemKind::Enum(..)
793 | ItemKind::Struct(..)
794 | ItemKind::Union(..)
795 | ItemKind::Trait(..)
ba9703b0
XL
796 | ItemKind::Impl { .. },
797 ..
798 })
799 | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(..), .. })
800 | Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(..), .. })
801 | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(..), .. })
802 | Node::Block(_) = node
803 {
e74abb32
XL
804 return Some(hir_id);
805 }
806 }
807 None
1a4d82fc
JJ
808 }
809
416331ca 810 /// Returns the defining scope for an opaque type definition.
5099ac24 811 pub fn get_defining_scope(self, id: HirId) -> HirId {
dc9dc135
XL
812 let mut scope = id;
813 loop {
e74abb32 814 scope = self.get_enclosing_scope(scope).unwrap_or(CRATE_HIR_ID);
5869c6ff
XL
815 if scope == CRATE_HIR_ID || !matches!(self.get(scope), Node::Block(_)) {
816 return scope;
dc9dc135
XL
817 }
818 }
1a4d82fc
JJ
819 }
820
5099ac24 821 pub fn get_foreign_abi(self, hir_id: HirId) -> Abi {
48663c56 822 let parent = self.get_parent_item(hir_id);
5099ac24 823 if let Some(node) = self.tcx.hir_owner(parent) {
94222f64
XL
824 if let OwnerNode::Item(Item { kind: ItemKind::ForeignMod { abi, .. }, .. }) = node.node
825 {
fc512014 826 return *abi;
7453a54e 827 }
1a4d82fc 828 }
5099ac24
FG
829 bug!(
830 "expected foreign mod or inlined parent, found {}",
2b03887a 831 self.node_to_string(HirId::make_owner(parent.def_id))
5099ac24 832 )
1a4d82fc
JJ
833 }
834
487cf647
FG
835 pub fn expect_owner(self, def_id: LocalDefId) -> OwnerNode<'hir> {
836 self.tcx
837 .hir_owner(OwnerId { def_id })
838 .unwrap_or_else(|| bug!("expected owner for {:?}", def_id))
839 .node
064997fb
FG
840 }
841
5099ac24 842 pub fn expect_item(self, id: LocalDefId) -> &'hir Item<'hir> {
2b03887a 843 match self.tcx.hir_owner(OwnerId { def_id: id }) {
3c0e092e 844 Some(Owner { node: OwnerNode::Item(item), .. }) => item,
a2a8927a 845 _ => bug!("expected item, found {}", self.node_to_string(HirId::make_owner(id))),
532ac7d7 846 }
9fa01778
XL
847 }
848
5099ac24 849 pub fn expect_impl_item(self, id: LocalDefId) -> &'hir ImplItem<'hir> {
2b03887a 850 match self.tcx.hir_owner(OwnerId { def_id: id }) {
3c0e092e 851 Some(Owner { node: OwnerNode::ImplItem(item), .. }) => item,
a2a8927a 852 _ => bug!("expected impl item, found {}", self.node_to_string(HirId::make_owner(id))),
9e0c209e
SL
853 }
854 }
855
5099ac24 856 pub fn expect_trait_item(self, id: LocalDefId) -> &'hir TraitItem<'hir> {
2b03887a 857 match self.tcx.hir_owner(OwnerId { def_id: id }) {
3c0e092e 858 Some(Owner { node: OwnerNode::TraitItem(item), .. }) => item,
a2a8927a 859 _ => bug!("expected trait item, found {}", self.node_to_string(HirId::make_owner(id))),
c1a9b12d
SL
860 }
861 }
862
9ffffee4
FG
863 pub fn get_fn_output(self, def_id: LocalDefId) -> Option<&'hir FnRetTy<'hir>> {
864 match self.tcx.hir_owner(OwnerId { def_id }) {
865 Some(Owner { node, .. }) => node.fn_decl().map(|fn_decl| &fn_decl.output),
866 _ => None,
867 }
868 }
869
5099ac24 870 pub fn expect_variant(self, id: HirId) -> &'hir Variant<'hir> {
dc9dc135 871 match self.find(id) {
b7449926 872 Some(Node::Variant(variant)) => variant,
dc9dc135 873 _ => bug!("expected variant, found {}", self.node_to_string(id)),
1a4d82fc
JJ
874 }
875 }
876
2b03887a 877 pub fn expect_foreign_item(self, id: OwnerId) -> &'hir ForeignItem<'hir> {
a2a8927a 878 match self.tcx.hir_owner(id) {
3c0e092e 879 Some(Owner { node: OwnerNode::ForeignItem(item), .. }) => item,
a2a8927a 880 _ => {
2b03887a
FG
881 bug!(
882 "expected foreign item, found {}",
883 self.node_to_string(HirId::make_owner(id.def_id))
884 )
a2a8927a 885 }
1a4d82fc
JJ
886 }
887 }
888
5099ac24 889 pub fn expect_expr(self, id: HirId) -> &'hir Expr<'hir> {
60c5eb7d 890 match self.find(id) {
48663c56 891 Some(Node::Expr(expr)) => expr,
60c5eb7d 892 _ => bug!("expected expr, found {}", self.node_to_string(id)),
48663c56 893 }
9fa01778
XL
894 }
895
923072b8
FG
896 #[inline]
897 fn opt_ident(self, id: HirId) -> Option<Ident> {
898 match self.get(id) {
064997fb 899 Node::Pat(&Pat { kind: PatKind::Binding(_, _, ident, _), .. }) => Some(ident),
923072b8
FG
900 // A `Ctor` doesn't have an identifier itself, but its parent
901 // struct/variant does. Compare with `hir::Map::opt_span`.
9c376795 902 Node::Ctor(..) => match self.find_parent(id)? {
923072b8
FG
903 Node::Item(item) => Some(item.ident),
904 Node::Variant(variant) => Some(variant.ident),
905 _ => unreachable!(),
906 },
907 node => node.ident(),
908 }
909 }
910
911 #[inline]
912 pub(super) fn opt_ident_span(self, id: HirId) -> Option<Span> {
913 self.opt_ident(id).map(|ident| ident.span)
914 }
915
9ffffee4
FG
916 #[inline]
917 pub fn ident(self, id: HirId) -> Ident {
918 self.opt_ident(id).unwrap()
919 }
920
923072b8 921 #[inline]
5099ac24 922 pub fn opt_name(self, id: HirId) -> Option<Symbol> {
923072b8 923 self.opt_ident(id).map(|ident| ident.name)
60c5eb7d
XL
924 }
925
5099ac24 926 pub fn name(self, id: HirId) -> Symbol {
923072b8 927 self.opt_name(id).unwrap_or_else(|| bug!("no name for {}", self.node_to_string(id)))
1a4d82fc
JJ
928 }
929
dc9dc135
XL
930 /// Given a node ID, gets a list of attributes associated with the AST
931 /// corresponding to the node-ID.
5099ac24 932 pub fn attrs(self, id: HirId) -> &'hir [ast::Attribute] {
6a06907d 933 self.tcx.hir_attrs(id.owner).get(id.local_id)
1a4d82fc
JJ
934 }
935
3dfed10e 936 /// Gets the span of the definition of the specified HIR node.
064997fb 937 /// This is used by `tcx.def_span`.
5099ac24 938 pub fn span(self, hir_id: HirId) -> Span {
5869c6ff
XL
939 self.opt_span(hir_id)
940 .unwrap_or_else(|| bug!("hir::map::Map::span: id not in map: {:?}", hir_id))
941 }
942
5099ac24 943 pub fn opt_span(self, hir_id: HirId) -> Option<Span> {
064997fb
FG
944 fn until_within(outer: Span, end: Span) -> Span {
945 if let Some(end) = end.find_ancestor_inside(outer) {
946 outer.with_hi(end.hi())
947 } else {
948 outer
949 }
950 }
951
952 fn named_span(item_span: Span, ident: Ident, generics: Option<&Generics<'_>>) -> Span {
953 if ident.name != kw::Empty {
954 let mut span = until_within(item_span, ident.span);
955 if let Some(g) = generics
956 && !g.span.is_dummy()
957 && let Some(g_span) = g.span.find_ancestor_inside(item_span)
958 {
959 span = span.to(g_span);
960 }
961 span
962 } else {
963 item_span
964 }
965 }
966
17df50a5 967 let span = match self.find(hir_id)? {
064997fb 968 // Function-like.
2b03887a
FG
969 Node::Item(Item { kind: ItemKind::Fn(sig, ..), span: outer_span, .. })
970 | Node::TraitItem(TraitItem {
971 kind: TraitItemKind::Fn(sig, ..),
972 span: outer_span,
973 ..
974 })
975 | Node::ImplItem(ImplItem {
976 kind: ImplItemKind::Fn(sig, ..), span: outer_span, ..
977 }) => {
978 // Ensure that the returned span has the item's SyntaxContext, and not the
979 // SyntaxContext of the visibility.
980 sig.span.find_ancestor_in_same_ctxt(*outer_span).unwrap_or(*outer_span)
981 }
064997fb
FG
982 // Constants and Statics.
983 Node::Item(Item {
984 kind:
985 ItemKind::Const(ty, ..)
986 | ItemKind::Static(ty, ..)
987 | ItemKind::Impl(Impl { self_ty: ty, .. }),
988 span: outer_span,
989 ..
990 })
991 | Node::TraitItem(TraitItem {
992 kind: TraitItemKind::Const(ty, ..),
993 span: outer_span,
994 ..
995 })
996 | Node::ImplItem(ImplItem {
997 kind: ImplItemKind::Const(ty, ..),
998 span: outer_span,
999 ..
1000 })
1001 | Node::ForeignItem(ForeignItem {
1002 kind: ForeignItemKind::Static(ty, ..),
1003 span: outer_span,
1004 ..
1005 }) => until_within(*outer_span, ty.span),
1006 // With generics and bounds.
1007 Node::Item(Item {
1008 kind: ItemKind::Trait(_, _, generics, bounds, _),
1009 span: outer_span,
1010 ..
1011 })
1012 | Node::TraitItem(TraitItem {
1013 kind: TraitItemKind::Type(bounds, _),
1014 generics,
1015 span: outer_span,
1016 ..
1017 }) => {
1018 let end = if let Some(b) = bounds.last() { b.span() } else { generics.span };
1019 until_within(*outer_span, end)
1020 }
1021 // Other cases.
5869c6ff 1022 Node::Item(item) => match &item.kind {
2b03887a
FG
1023 ItemKind::Use(path, _) => {
1024 // Ensure that the returned span has the item's SyntaxContext, and not the
1025 // SyntaxContext of the path.
1026 path.span.find_ancestor_in_same_ctxt(item.span).unwrap_or(item.span)
1027 }
064997fb 1028 _ => named_span(item.span, item.ident, item.kind.generics()),
3dfed10e 1029 },
064997fb
FG
1030 Node::Variant(variant) => named_span(variant.span, variant.ident, None),
1031 Node::ImplItem(item) => named_span(item.span, item.ident, Some(item.generics)),
1032 Node::ForeignItem(item) => match item.kind {
1033 ForeignItemKind::Fn(decl, _, _) => until_within(item.span, decl.output.span()),
1034 _ => named_span(item.span, item.ident, None),
3dfed10e 1035 },
9c376795 1036 Node::Ctor(_) => return self.opt_span(self.parent_id(hir_id)),
2b03887a
FG
1037 Node::Expr(Expr {
1038 kind: ExprKind::Closure(Closure { fn_decl_span, .. }),
1039 span,
1040 ..
1041 }) => {
1042 // Ensure that the returned span has the item's SyntaxContext.
487cf647 1043 fn_decl_span.find_ancestor_inside(*span).unwrap_or(*span)
064997fb
FG
1044 }
1045 _ => self.span_with_body(hir_id),
1046 };
2b03887a 1047 debug_assert_eq!(span.ctxt(), self.span_with_body(hir_id).ctxt());
064997fb
FG
1048 Some(span)
1049 }
1050
1051 /// Like `hir.span()`, but includes the body of items
1052 /// (instead of just the item header)
1053 pub fn span_with_body(self, hir_id: HirId) -> Span {
1054 match self.get(hir_id) {
1055 Node::Param(param) => param.span,
1056 Node::Item(item) => item.span,
1057 Node::ForeignItem(foreign_item) => foreign_item.span,
1058 Node::TraitItem(trait_item) => trait_item.span,
1059 Node::ImplItem(impl_item) => impl_item.span,
5869c6ff
XL
1060 Node::Variant(variant) => variant.span,
1061 Node::Field(field) => field.span,
1062 Node::AnonConst(constant) => self.body(constant.body).value.span,
1063 Node::Expr(expr) => expr.span,
f2b60f7d 1064 Node::ExprField(field) => field.span,
5869c6ff 1065 Node::Stmt(stmt) => stmt.span,
923072b8
FG
1066 Node::PathSegment(seg) => {
1067 let ident_span = seg.ident.span;
1068 ident_span
1069 .with_hi(seg.args.map_or_else(|| ident_span.hi(), |args| args.span_ext.hi()))
1070 }
5869c6ff 1071 Node::Ty(ty) => ty.span,
923072b8 1072 Node::TypeBinding(tb) => tb.span,
5869c6ff 1073 Node::TraitRef(tr) => tr.path.span,
5869c6ff 1074 Node::Pat(pat) => pat.span,
f2b60f7d 1075 Node::PatField(field) => field.span,
5869c6ff
XL
1076 Node::Arm(arm) => arm.span,
1077 Node::Block(block) => block.span,
9c376795 1078 Node::Ctor(..) => self.span_with_body(self.parent_id(hir_id)),
487cf647 1079 Node::Lifetime(lifetime) => lifetime.ident.span,
5869c6ff 1080 Node::GenericParam(param) => param.span,
94222f64 1081 Node::Infer(i) => i.span,
5869c6ff 1082 Node::Local(local) => local.span,
04454e1e 1083 Node::Crate(item) => item.spans.inner_span,
3dfed10e
XL
1084 }
1085 }
1086
5099ac24 1087 pub fn span_if_local(self, id: DefId) -> Option<Span> {
9ffffee4 1088 id.is_local().then(|| self.tcx.def_span(id))
b039eaaf
SL
1089 }
1090
5099ac24 1091 pub fn res_span(self, res: Res) -> Option<Span> {
e74abb32
XL
1092 match res {
1093 Res::Err => None,
1094 Res::Local(id) => Some(self.span(id)),
1095 res => self.span_if_local(res.opt_def_id()?),
1096 }
1097 }
1098
ba9703b0
XL
1099 /// Get a representation of this `id` for debugging purposes.
1100 /// NOTE: Do NOT use this in diagnostics!
5099ac24 1101 pub fn node_to_string(self, id: HirId) -> String {
ba9703b0 1102 hir_id_to_string(self, id)
9fa01778 1103 }
94222f64
XL
1104
1105 /// Returns the HirId of `N` in `struct Foo<const N: usize = { ... }>` when
1106 /// called with the HirId for the `{ ... }` anon const
487cf647 1107 pub fn opt_const_param_default_param_def_id(self, anon_const: HirId) -> Option<LocalDefId> {
9c376795 1108 match self.get_parent(anon_const) {
94222f64 1109 Node::GenericParam(GenericParam {
487cf647 1110 def_id: param_id,
94222f64
XL
1111 kind: GenericParamKind::Const { .. },
1112 ..
1113 }) => Some(*param_id),
1114 _ => None,
1115 }
1116 }
1a4d82fc
JJ
1117}
1118
dfeec247 1119impl<'hir> intravisit::Map<'hir> for Map<'hir> {
ba9703b0 1120 fn find(&self, hir_id: HirId) -> Option<Node<'hir>> {
5099ac24 1121 (*self).find(hir_id)
ba9703b0
XL
1122 }
1123
dfeec247 1124 fn body(&self, id: BodyId) -> &'hir Body<'hir> {
5099ac24 1125 (*self).body(id)
dfeec247
XL
1126 }
1127
6a06907d 1128 fn item(&self, id: ItemId) -> &'hir Item<'hir> {
5099ac24 1129 (*self).item(id)
dfeec247
XL
1130 }
1131
1132 fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir> {
5099ac24 1133 (*self).trait_item(id)
dfeec247
XL
1134 }
1135
1136 fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir> {
5099ac24 1137 (*self).impl_item(id)
dfeec247 1138 }
fc512014
XL
1139
1140 fn foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir> {
5099ac24 1141 (*self).foreign_item(id)
fc512014 1142 }
dfeec247
XL
1143}
1144
353b0b11 1145pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh {
3c0e092e 1146 let krate = tcx.hir_crate(());
353b0b11 1147 let hir_body_hash = krate.opt_hir_hash.expect("HIR hash missing while computing crate hash");
17df50a5 1148
136023e0 1149 let upstream_crates = upstream_crates(tcx);
17df50a5 1150
923072b8
FG
1151 let resolutions = tcx.resolutions(());
1152
17df50a5
XL
1153 // We hash the final, remapped names of all local source files so we
1154 // don't have to include the path prefix remapping commandline args.
1155 // If we included the full mapping in the SVH, we could only have
1156 // reproducible builds by compiling from the same directory. So we just
1157 // hash the result of the mapping instead of the mapping itself.
1158 let mut source_file_names: Vec<_> = tcx
1159 .sess
1160 .source_map()
1161 .files()
1162 .iter()
1163 .filter(|source_file| source_file.cnum == LOCAL_CRATE)
1164 .map(|source_file| source_file.name_hash)
1165 .collect();
1166
1167 source_file_names.sort_unstable();
1168
49aad941
FG
1169 // We have to take care of debugger visualizers explicitly. The HIR (and
1170 // thus `hir_body_hash`) contains the #[debugger_visualizer] attributes but
1171 // these attributes only store the file path to the visualizer file, not
1172 // their content. Yet that content is exported into crate metadata, so any
1173 // changes to it need to be reflected in the crate hash.
1174 let debugger_visualizers: Vec<_> = tcx
1175 .debugger_visualizers(LOCAL_CRATE)
1176 .iter()
1177 // We ignore the path to the visualizer file since it's not going to be
1178 // encoded in crate metadata and we already hash the full contents of
1179 // the file.
1180 .map(DebuggerVisualizerFile::path_erased)
1181 .collect();
1182
064997fb
FG
1183 let crate_hash: Fingerprint = tcx.with_stable_hashing_context(|mut hcx| {
1184 let mut stable_hasher = StableHasher::new();
1185 hir_body_hash.hash_stable(&mut hcx, &mut stable_hasher);
1186 upstream_crates.hash_stable(&mut hcx, &mut stable_hasher);
1187 source_file_names.hash_stable(&mut hcx, &mut stable_hasher);
49aad941 1188 debugger_visualizers.hash_stable(&mut hcx, &mut stable_hasher);
9c376795 1189 if tcx.sess.opts.incremental_relative_spans() {
064997fb
FG
1190 let definitions = tcx.definitions_untracked();
1191 let mut owner_spans: Vec<_> = krate
1192 .owners
1193 .iter_enumerated()
1194 .filter_map(|(def_id, info)| {
1195 let _ = info.as_owner()?;
1196 let def_path_hash = definitions.def_path_hash(def_id);
9c376795 1197 let span = tcx.source_span(def_id);
064997fb
FG
1198 debug_assert_eq!(span.parent(), None);
1199 Some((def_path_hash, span))
1200 })
1201 .collect();
1202 owner_spans.sort_unstable_by_key(|bn| bn.0);
1203 owner_spans.hash_stable(&mut hcx, &mut stable_hasher);
1204 }
1205 tcx.sess.opts.dep_tracking_hash(true).hash_stable(&mut hcx, &mut stable_hasher);
1206 tcx.sess.local_stable_crate_id().hash_stable(&mut hcx, &mut stable_hasher);
1207 // Hash visibility information since it does not appear in HIR.
1208 resolutions.visibilities.hash_stable(&mut hcx, &mut stable_hasher);
1209 resolutions.has_pub_restricted.hash_stable(&mut hcx, &mut stable_hasher);
1210 stable_hasher.finish()
1211 });
17df50a5 1212
49aad941 1213 Svh::new(crate_hash)
17df50a5 1214}
1a4d82fc 1215
136023e0
XL
1216fn upstream_crates(tcx: TyCtxt<'_>) -> Vec<(StableCrateId, Svh)> {
1217 let mut upstream_crates: Vec<_> = tcx
1218 .crates(())
17df50a5
XL
1219 .iter()
1220 .map(|&cnum| {
923072b8 1221 let stable_crate_id = tcx.stable_crate_id(cnum);
136023e0
XL
1222 let hash = tcx.crate_hash(cnum);
1223 (stable_crate_id, hash)
17df50a5
XL
1224 })
1225 .collect();
136023e0 1226 upstream_crates.sort_unstable_by_key(|&(stable_crate_id, _)| stable_crate_id);
17df50a5 1227 upstream_crates
1a4d82fc
JJ
1228}
1229
5099ac24 1230fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
49aad941 1231 let path_str = |def_id: LocalDefId| map.tcx.def_path_str(def_id);
54a0048b 1232
ba9703b0 1233 let span_str = || map.tcx.sess.source_map().span_to_snippet(map.span(id)).unwrap_or_default();
9ffffee4 1234 let node_str = |prefix| format!("{id} ({prefix} `{}`)", span_str());
ba9703b0 1235
dc9dc135 1236 match map.find(id) {
b7449926 1237 Some(Node::Item(item)) => {
e74abb32 1238 let item_str = match item.kind {
8faf50e0
XL
1239 ItemKind::ExternCrate(..) => "extern crate",
1240 ItemKind::Use(..) => "use",
1241 ItemKind::Static(..) => "static",
1242 ItemKind::Const(..) => "const",
1243 ItemKind::Fn(..) => "fn",
94222f64 1244 ItemKind::Macro(..) => "macro",
8faf50e0 1245 ItemKind::Mod(..) => "mod",
fc512014 1246 ItemKind::ForeignMod { .. } => "foreign mod",
8faf50e0 1247 ItemKind::GlobalAsm(..) => "global asm",
416331ca 1248 ItemKind::TyAlias(..) => "ty",
f2b60f7d
FG
1249 ItemKind::OpaqueTy(ref opaque) => {
1250 if opaque.in_trait {
1251 "opaque type in trait"
1252 } else {
1253 "opaque type"
1254 }
1255 }
8faf50e0
XL
1256 ItemKind::Enum(..) => "enum",
1257 ItemKind::Struct(..) => "struct",
1258 ItemKind::Union(..) => "union",
1259 ItemKind::Trait(..) => "trait",
1260 ItemKind::TraitAlias(..) => "trait alias",
dfeec247 1261 ItemKind::Impl { .. } => "impl",
1a4d82fc 1262 };
9ffffee4 1263 format!("{id} ({item_str} {})", path_str(item.owner_id.def_id))
487cf647
FG
1264 }
1265 Some(Node::ForeignItem(item)) => {
9ffffee4 1266 format!("{id} (foreign item {})", path_str(item.owner_id.def_id))
487cf647
FG
1267 }
1268 Some(Node::ImplItem(ii)) => {
1269 let kind = match ii.kind {
1270 ImplItemKind::Const(..) => "assoc const",
1271 ImplItemKind::Fn(..) => "method",
1272 ImplItemKind::Type(_) => "assoc type",
1273 };
9ffffee4 1274 format!("{id} ({kind} `{}` in {})", ii.ident, path_str(ii.owner_id.def_id))
1a4d82fc 1275 }
b7449926 1276 Some(Node::TraitItem(ti)) => {
e74abb32 1277 let kind = match ti.kind {
32a655c1 1278 TraitItemKind::Const(..) => "assoc constant",
ba9703b0 1279 TraitItemKind::Fn(..) => "trait method",
32a655c1 1280 TraitItemKind::Type(..) => "assoc type",
c34b1796
AL
1281 };
1282
9ffffee4 1283 format!("{id} ({kind} `{}` in {})", ti.ident, path_str(ti.owner_id.def_id))
c34b1796 1284 }
b7449926 1285 Some(Node::Variant(ref variant)) => {
9ffffee4 1286 format!("{id} (variant `{}` in {})", variant.ident, path_str(variant.def_id))
1a4d82fc 1287 }
b7449926 1288 Some(Node::Field(ref field)) => {
9ffffee4 1289 format!("{id} (field `{}` in {})", field.ident, path_str(field.def_id))
1a4d82fc 1290 }
ba9703b0
XL
1291 Some(Node::AnonConst(_)) => node_str("const"),
1292 Some(Node::Expr(_)) => node_str("expr"),
f2b60f7d 1293 Some(Node::ExprField(_)) => node_str("expr field"),
ba9703b0
XL
1294 Some(Node::Stmt(_)) => node_str("stmt"),
1295 Some(Node::PathSegment(_)) => node_str("path segment"),
1296 Some(Node::Ty(_)) => node_str("type"),
923072b8 1297 Some(Node::TypeBinding(_)) => node_str("type binding"),
ba9703b0 1298 Some(Node::TraitRef(_)) => node_str("trait ref"),
ba9703b0 1299 Some(Node::Pat(_)) => node_str("pat"),
f2b60f7d 1300 Some(Node::PatField(_)) => node_str("pattern field"),
ba9703b0
XL
1301 Some(Node::Param(_)) => node_str("param"),
1302 Some(Node::Arm(_)) => node_str("arm"),
1303 Some(Node::Block(_)) => node_str("block"),
94222f64 1304 Some(Node::Infer(_)) => node_str("infer"),
ba9703b0 1305 Some(Node::Local(_)) => node_str("local"),
487cf647 1306 Some(Node::Ctor(ctor)) => format!(
9ffffee4 1307 "{id} (ctor {})",
487cf647 1308 ctor.ctor_def_id().map_or("<missing path>".into(), |def_id| path_str(def_id)),
487cf647 1309 ),
ba9703b0 1310 Some(Node::Lifetime(_)) => node_str("lifetime"),
487cf647 1311 Some(Node::GenericParam(ref param)) => {
9ffffee4 1312 format!("{id} (generic_param {})", path_str(param.def_id))
487cf647 1313 }
9ffffee4
FG
1314 Some(Node::Crate(..)) => String::from("(root_crate)"),
1315 None => format!("{id} (unknown node)"),
1a4d82fc
JJ
1316 }
1317}
c295e0f8
XL
1318
1319pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalDefId) -> ModuleItems {
064997fb 1320 let mut collector = ItemCollector::new(tcx, false);
c295e0f8
XL
1321
1322 let (hir_mod, span, hir_id) = tcx.hir().get_module(module_id);
1323 collector.visit_mod(hir_mod, span, hir_id);
1324
064997fb
FG
1325 let ItemCollector {
1326 submodules,
1327 items,
1328 trait_items,
1329 impl_items,
1330 foreign_items,
1331 body_owners,
1332 ..
1333 } = collector;
c295e0f8
XL
1334 return ModuleItems {
1335 submodules: submodules.into_boxed_slice(),
1336 items: items.into_boxed_slice(),
1337 trait_items: trait_items.into_boxed_slice(),
1338 impl_items: impl_items.into_boxed_slice(),
1339 foreign_items: foreign_items.into_boxed_slice(),
064997fb 1340 body_owners: body_owners.into_boxed_slice(),
c295e0f8 1341 };
c295e0f8 1342}
04454e1e
FG
1343
1344pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
064997fb 1345 let mut collector = ItemCollector::new(tcx, true);
04454e1e 1346
064997fb
FG
1347 // A "crate collector" and "module collector" start at a
1348 // module item (the former starts at the crate root) but only
1349 // the former needs to collect it. ItemCollector does not do this for us.
2b03887a 1350 collector.submodules.push(CRATE_OWNER_ID);
04454e1e
FG
1351 tcx.hir().walk_toplevel_module(&mut collector);
1352
064997fb
FG
1353 let ItemCollector {
1354 submodules,
1355 items,
1356 trait_items,
1357 impl_items,
1358 foreign_items,
1359 body_owners,
1360 ..
1361 } = collector;
04454e1e
FG
1362
1363 return ModuleItems {
1364 submodules: submodules.into_boxed_slice(),
1365 items: items.into_boxed_slice(),
1366 trait_items: trait_items.into_boxed_slice(),
1367 impl_items: impl_items.into_boxed_slice(),
1368 foreign_items: foreign_items.into_boxed_slice(),
064997fb 1369 body_owners: body_owners.into_boxed_slice(),
04454e1e 1370 };
064997fb 1371}
04454e1e 1372
064997fb
FG
1373struct ItemCollector<'tcx> {
1374 // When true, it collects all items in the create,
1375 // otherwise it collects items in some module.
1376 crate_collector: bool,
1377 tcx: TyCtxt<'tcx>,
2b03887a 1378 submodules: Vec<OwnerId>,
064997fb
FG
1379 items: Vec<ItemId>,
1380 trait_items: Vec<TraitItemId>,
1381 impl_items: Vec<ImplItemId>,
1382 foreign_items: Vec<ForeignItemId>,
1383 body_owners: Vec<LocalDefId>,
1384}
1385
1386impl<'tcx> ItemCollector<'tcx> {
1387 fn new(tcx: TyCtxt<'tcx>, crate_collector: bool) -> ItemCollector<'tcx> {
1388 ItemCollector {
1389 crate_collector,
1390 tcx,
1391 submodules: Vec::default(),
1392 items: Vec::default(),
1393 trait_items: Vec::default(),
1394 impl_items: Vec::default(),
1395 foreign_items: Vec::default(),
1396 body_owners: Vec::default(),
1397 }
04454e1e 1398 }
064997fb
FG
1399}
1400
1401impl<'hir> Visitor<'hir> for ItemCollector<'hir> {
1402 type NestedFilter = nested_filter::All;
04454e1e 1403
064997fb
FG
1404 fn nested_visit_map(&mut self) -> Self::Map {
1405 self.tcx.hir()
1406 }
04454e1e 1407
064997fb
FG
1408 fn visit_item(&mut self, item: &'hir Item<'hir>) {
1409 if associated_body(Node::Item(item)).is_some() {
2b03887a 1410 self.body_owners.push(item.owner_id.def_id);
04454e1e
FG
1411 }
1412
064997fb
FG
1413 self.items.push(item.item_id());
1414
1415 // Items that are modules are handled here instead of in visit_mod.
1416 if let ItemKind::Mod(module) = &item.kind {
2b03887a 1417 self.submodules.push(item.owner_id);
064997fb
FG
1418 // A module collector does not recurse inside nested modules.
1419 if self.crate_collector {
1420 intravisit::walk_mod(self, module, item.hir_id());
1421 }
1422 } else {
04454e1e
FG
1423 intravisit::walk_item(self, item)
1424 }
064997fb 1425 }
04454e1e 1426
064997fb
FG
1427 fn visit_foreign_item(&mut self, item: &'hir ForeignItem<'hir>) {
1428 self.foreign_items.push(item.foreign_item_id());
1429 intravisit::walk_foreign_item(self, item)
1430 }
04454e1e 1431
064997fb 1432 fn visit_anon_const(&mut self, c: &'hir AnonConst) {
487cf647 1433 self.body_owners.push(c.def_id);
064997fb
FG
1434 intravisit::walk_anon_const(self, c)
1435 }
1436
1437 fn visit_expr(&mut self, ex: &'hir Expr<'hir>) {
487cf647
FG
1438 if let ExprKind::Closure(closure) = ex.kind {
1439 self.body_owners.push(closure.def_id);
04454e1e 1440 }
064997fb
FG
1441 intravisit::walk_expr(self, ex)
1442 }
04454e1e 1443
064997fb
FG
1444 fn visit_trait_item(&mut self, item: &'hir TraitItem<'hir>) {
1445 if associated_body(Node::TraitItem(item)).is_some() {
2b03887a 1446 self.body_owners.push(item.owner_id.def_id);
04454e1e
FG
1447 }
1448
064997fb
FG
1449 self.trait_items.push(item.trait_item_id());
1450 intravisit::walk_trait_item(self, item)
1451 }
1452
1453 fn visit_impl_item(&mut self, item: &'hir ImplItem<'hir>) {
1454 if associated_body(Node::ImplItem(item)).is_some() {
2b03887a 1455 self.body_owners.push(item.owner_id.def_id);
04454e1e 1456 }
064997fb
FG
1457
1458 self.impl_items.push(item.impl_item_id());
1459 intravisit::walk_impl_item(self, item)
04454e1e
FG
1460 }
1461}