1pub mod map;
6pub mod nested_filter;
7pub mod place;
8
9use std::sync::Arc;
10
11use rustc_ast::{self as ast};
12use rustc_data_structures::fingerprint::Fingerprint;
13use rustc_data_structures::fx::FxIndexSet;
14use rustc_data_structures::sorted_map::SortedMap;
15use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
16use rustc_data_structures::steal::Steal;
17use rustc_data_structures::sync::{DynSend, DynSync, spawn, try_par_for_each_in};
18use rustc_hir::def::{DefKind, Res};
19use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
20use rustc_hir::lints::DelayedLint;
21use rustc_hir::*;
22use rustc_index::IndexVec;
23use rustc_macros::{Decodable, Encodable, HashStable};
24use rustc_span::{ErrorGuaranteed, ExpnId, HashStableContext, Span};
25
26use crate::query::Providers;
27use crate::ty::{ResolverAstLowering, TyCtxt};
28
29#[derive(#[automatically_derived]
impl<'hir> ::core::fmt::Debug for Crate<'hir> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field4_finish(f, "Crate",
"owners", &self.owners, "delayed_ids", &self.delayed_ids,
"delayed_resolver", &self.delayed_resolver, "opt_hir_hash",
&&self.opt_hir_hash)
}
}Debug)]
36pub struct Crate<'hir> {
37 owners: IndexVec<LocalDefId, MaybeOwner<'hir>>,
39 pub delayed_ids: FxIndexSet<LocalDefId>,
41 pub delayed_resolver: Steal<(ResolverAstLowering<'hir>, Arc<ast::Crate>)>,
44 pub opt_hir_hash: Option<Fingerprint>,
46}
47
48impl<'hir> Crate<'hir> {
49 pub fn new(
50 owners: IndexVec<LocalDefId, MaybeOwner<'hir>>,
51 delayed_ids: FxIndexSet<LocalDefId>,
52 delayed_resolver: Steal<(ResolverAstLowering<'hir>, Arc<ast::Crate>)>,
53 opt_hir_hash: Option<Fingerprint>,
54 ) -> Crate<'hir> {
55 Crate { owners, delayed_ids, delayed_resolver, opt_hir_hash }
56 }
57
58 pub fn owner(&self, tcx: TyCtxt<'hir>, def_id: LocalDefId) -> MaybeOwner<'hir> {
63 if let Some(owner) = self.owners.get(def_id)
67 && (self.delayed_ids.is_empty()
68 || !#[allow(non_exhaustive_omitted_patterns)] match owner {
MaybeOwner::Phantom | MaybeOwner::Delayed(_) => true,
_ => false,
}matches!(owner, MaybeOwner::Phantom | MaybeOwner::Delayed(_)))
69 {
70 return *owner;
71 }
72
73 if self.delayed_ids.contains(&def_id) {
74 tcx.ensure_done().lower_delayed_owner(def_id);
75 }
76
77 tcx.delayed_owner(def_id)
78 }
79}
80
81impl<Hcx: HashStableContext> HashStable<Hcx> for Crate<'_> {
82 fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
83 let Crate { opt_hir_hash, .. } = self;
84 opt_hir_hash.unwrap().hash_stable(hcx, hasher)
85 }
86}
87
88#[derive(#[automatically_derived]
impl ::core::fmt::Debug for ModuleItems {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
let names: &'static _ =
&["add_root", "submodules", "free_items", "trait_items",
"impl_items", "foreign_items", "opaques", "body_owners",
"nested_bodies", "delayed_lint_items", "eiis"];
let values: &[&dyn ::core::fmt::Debug] =
&[&self.add_root, &self.submodules, &self.free_items,
&self.trait_items, &self.impl_items, &self.foreign_items,
&self.opaques, &self.body_owners, &self.nested_bodies,
&self.delayed_lint_items, &&self.eiis];
::core::fmt::Formatter::debug_struct_fields_finish(f, "ModuleItems",
names, values)
}
}Debug, const _: () =
{
impl<'__ctx>
::rustc_data_structures::stable_hasher::HashStable<::rustc_middle::ich::StableHashingContext<'__ctx>>
for ModuleItems {
#[inline]
fn hash_stable(&self,
__hcx: &mut ::rustc_middle::ich::StableHashingContext<'__ctx>,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
match *self {
ModuleItems {
add_root: ref __binding_0,
submodules: ref __binding_1,
free_items: ref __binding_2,
trait_items: ref __binding_3,
impl_items: ref __binding_4,
foreign_items: ref __binding_5,
opaques: ref __binding_6,
body_owners: ref __binding_7,
nested_bodies: ref __binding_8,
delayed_lint_items: ref __binding_9,
eiis: ref __binding_10 } => {
{ __binding_0.hash_stable(__hcx, __hasher); }
{ __binding_1.hash_stable(__hcx, __hasher); }
{ __binding_2.hash_stable(__hcx, __hasher); }
{ __binding_3.hash_stable(__hcx, __hasher); }
{ __binding_4.hash_stable(__hcx, __hasher); }
{ __binding_5.hash_stable(__hcx, __hasher); }
{ __binding_6.hash_stable(__hcx, __hasher); }
{ __binding_7.hash_stable(__hcx, __hasher); }
{ __binding_8.hash_stable(__hcx, __hasher); }
{ __binding_9.hash_stable(__hcx, __hasher); }
{ __binding_10.hash_stable(__hcx, __hasher); }
}
}
}
}
};HashStable, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for ModuleItems {
fn encode(&self, __encoder: &mut __E) {
match *self {
ModuleItems {
add_root: ref __binding_0,
submodules: ref __binding_1,
free_items: ref __binding_2,
trait_items: ref __binding_3,
impl_items: ref __binding_4,
foreign_items: ref __binding_5,
opaques: ref __binding_6,
body_owners: ref __binding_7,
nested_bodies: ref __binding_8,
delayed_lint_items: ref __binding_9,
eiis: ref __binding_10 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_1,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_2,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_3,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_4,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_5,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_6,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_7,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_8,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_9,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_10,
__encoder);
}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for ModuleItems {
fn decode(__decoder: &mut __D) -> Self {
ModuleItems {
add_root: ::rustc_serialize::Decodable::decode(__decoder),
submodules: ::rustc_serialize::Decodable::decode(__decoder),
free_items: ::rustc_serialize::Decodable::decode(__decoder),
trait_items: ::rustc_serialize::Decodable::decode(__decoder),
impl_items: ::rustc_serialize::Decodable::decode(__decoder),
foreign_items: ::rustc_serialize::Decodable::decode(__decoder),
opaques: ::rustc_serialize::Decodable::decode(__decoder),
body_owners: ::rustc_serialize::Decodable::decode(__decoder),
nested_bodies: ::rustc_serialize::Decodable::decode(__decoder),
delayed_lint_items: ::rustc_serialize::Decodable::decode(__decoder),
eiis: ::rustc_serialize::Decodable::decode(__decoder),
}
}
}
};Decodable)]
91pub struct ModuleItems {
92 add_root: bool,
95 submodules: Box<[OwnerId]>,
96 free_items: Box<[ItemId]>,
97 trait_items: Box<[TraitItemId]>,
98 impl_items: Box<[ImplItemId]>,
99 foreign_items: Box<[ForeignItemId]>,
100 opaques: Box<[LocalDefId]>,
101 body_owners: Box<[LocalDefId]>,
102 nested_bodies: Box<[LocalDefId]>,
103 delayed_lint_items: Box<[OwnerId]>,
105
106 eiis: Box<[LocalDefId]>,
108}
109
110impl ModuleItems {
111 pub fn free_items(&self) -> impl Iterator<Item = ItemId> {
118 self.free_items.iter().copied()
119 }
120
121 pub fn trait_items(&self) -> impl Iterator<Item = TraitItemId> {
122 self.trait_items.iter().copied()
123 }
124
125 pub fn delayed_lint_items(&self) -> impl Iterator<Item = OwnerId> {
126 self.delayed_lint_items.iter().copied()
127 }
128
129 pub fn eiis(&self) -> impl Iterator<Item = LocalDefId> {
130 self.eiis.iter().copied()
131 }
132
133 pub fn impl_items(&self) -> impl Iterator<Item = ImplItemId> {
136 self.impl_items.iter().copied()
137 }
138
139 pub fn foreign_items(&self) -> impl Iterator<Item = ForeignItemId> {
140 self.foreign_items.iter().copied()
141 }
142
143 pub fn owners(&self) -> impl Iterator<Item = OwnerId> {
144 self.add_root
145 .then_some(CRATE_OWNER_ID)
146 .into_iter()
147 .chain(self.free_items.iter().map(|id| id.owner_id))
148 .chain(self.trait_items.iter().map(|id| id.owner_id))
149 .chain(self.impl_items.iter().map(|id| id.owner_id))
150 .chain(self.foreign_items.iter().map(|id| id.owner_id))
151 }
152
153 pub fn opaques(&self) -> impl Iterator<Item = LocalDefId> {
154 self.opaques.iter().copied()
155 }
156
157 pub fn nested_bodies(&self) -> impl Iterator<Item = LocalDefId> {
159 self.nested_bodies.iter().copied()
160 }
161
162 pub fn definitions(&self) -> impl Iterator<Item = LocalDefId> {
163 self.owners().map(|id| id.def_id)
164 }
165
166 pub fn par_nested_bodies(
168 &self,
169 f: impl Fn(LocalDefId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
170 ) -> Result<(), ErrorGuaranteed> {
171 try_par_for_each_in(&self.nested_bodies[..], |&&id| f(id))
172 }
173
174 pub fn par_items(
175 &self,
176 f: impl Fn(ItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
177 ) -> Result<(), ErrorGuaranteed> {
178 try_par_for_each_in(&self.free_items[..], |&&id| f(id))
179 }
180
181 pub fn par_trait_items(
182 &self,
183 f: impl Fn(TraitItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
184 ) -> Result<(), ErrorGuaranteed> {
185 try_par_for_each_in(&self.trait_items[..], |&&id| f(id))
186 }
187
188 pub fn par_impl_items(
189 &self,
190 f: impl Fn(ImplItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
191 ) -> Result<(), ErrorGuaranteed> {
192 try_par_for_each_in(&self.impl_items[..], |&&id| f(id))
193 }
194
195 pub fn par_foreign_items(
196 &self,
197 f: impl Fn(ForeignItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
198 ) -> Result<(), ErrorGuaranteed> {
199 try_par_for_each_in(&self.foreign_items[..], |&&id| f(id))
200 }
201
202 pub fn par_opaques(
203 &self,
204 f: impl Fn(LocalDefId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
205 ) -> Result<(), ErrorGuaranteed> {
206 try_par_for_each_in(&self.opaques[..], |&&id| f(id))
207 }
208}
209
210impl<'tcx> TyCtxt<'tcx> {
211 pub fn force_delayed_owners_lowering(self) {
212 let krate = self.hir_crate(());
213 self.ensure_done().hir_crate_items(());
214
215 for &id in &krate.delayed_ids {
216 self.ensure_done().lower_delayed_owner(id);
217 }
218
219 let (_, krate) = krate.delayed_resolver.steal();
220 let prof = self.sess.prof.clone();
221
222 spawn(move || {
224 let _timer = prof.verbose_generic_activity("drop_ast");
225 drop(krate);
226 });
227 }
228
229 pub fn parent_module(self, id: HirId) -> LocalModDefId {
230 if !id.is_owner() && self.def_kind(id.owner) == DefKind::Mod {
231 LocalModDefId::new_unchecked(id.owner.def_id)
232 } else {
233 self.parent_module_from_def_id(id.owner.def_id)
234 }
235 }
236
237 pub fn parent_module_from_def_id(self, mut id: LocalDefId) -> LocalModDefId {
238 while let Some(parent) = self.opt_local_parent(id) {
239 id = parent;
240 if self.def_kind(id) == DefKind::Mod {
241 break;
242 }
243 }
244 LocalModDefId::new_unchecked(id)
245 }
246
247 pub fn is_foreign_item(self, def_id: impl Into<DefId>) -> bool {
249 self.opt_parent(def_id.into())
250 .is_some_and(|parent| #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(parent) {
DefKind::ForeignMod => true,
_ => false,
}matches!(self.def_kind(parent), DefKind::ForeignMod))
251 }
252
253 pub fn hash_owner_nodes(
254 self,
255 node: OwnerNode<'_>,
256 bodies: &SortedMap<ItemLocalId, &Body<'_>>,
257 attrs: &SortedMap<ItemLocalId, &[Attribute]>,
258 delayed_lints: &[DelayedLint],
259 define_opaque: Option<&[(Span, LocalDefId)]>,
260 ) -> Hashes {
261 if !self.needs_crate_hash() {
262 return Hashes {
263 opt_hash_including_bodies: None,
264 attrs_hash: None,
265 delayed_lints_hash: None,
266 };
267 }
268
269 self.with_stable_hashing_context(|mut hcx| {
270 let mut stable_hasher = StableHasher::new();
271 node.hash_stable(&mut hcx, &mut stable_hasher);
272 bodies.hash_stable(&mut hcx, &mut stable_hasher);
274 let h1 = stable_hasher.finish();
275
276 let mut stable_hasher = StableHasher::new();
277 attrs.hash_stable(&mut hcx, &mut stable_hasher);
278
279 define_opaque.hash_stable(&mut hcx, &mut stable_hasher);
281
282 let h2 = stable_hasher.finish();
283
284 let mut stable_hasher = StableHasher::new();
286 delayed_lints.hash_stable(&mut hcx, &mut stable_hasher);
287 let h3 = stable_hasher.finish();
288
289 Hashes {
290 opt_hash_including_bodies: Some(h1),
291 attrs_hash: Some(h2),
292 delayed_lints_hash: Some(h3),
293 }
294 })
295 }
296
297 pub fn qpath_is_lang_item(self, qpath: QPath<'_>, lang_item: LangItem) -> bool {
298 self.qpath_lang_item(qpath) == Some(lang_item)
299 }
300
301 pub fn qpath_lang_item(self, qpath: QPath<'_>) -> Option<LangItem> {
303 if let QPath::Resolved(_, path) = qpath
304 && let Res::Def(_, def_id) = path.res
305 {
306 return self.lang_items().from_def_id(def_id);
307 }
308 None
309 }
310
311 pub fn expr_guaranteed_to_constitute_read_for_never(self, expr: &Expr<'_>) -> bool {
323 if !expr.is_syntactic_place_expr() {
329 return true;
330 }
331
332 let parent_node = self.parent_hir_node(expr.hir_id);
333 match parent_node {
334 Node::Expr(parent_expr) => {
335 match parent_expr.kind {
336 ExprKind::AddrOf(..) | ExprKind::Field(..) => false,
340
341 ExprKind::Type(..) | ExprKind::UnsafeBinderCast(..) => {
344 self.expr_guaranteed_to_constitute_read_for_never(parent_expr)
345 }
346
347 ExprKind::Assign(lhs, _, _) => {
348 expr.hir_id != lhs.hir_id
350 }
351
352 ExprKind::Match(scrutinee, arms, _) => {
355 match (&scrutinee.hir_id, &expr.hir_id) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::None);
}
}
};assert_eq!(scrutinee.hir_id, expr.hir_id);
356 arms.iter().all(|arm| arm.pat.is_guaranteed_to_constitute_read_for_never())
357 }
358 ExprKind::Let(LetExpr { init, pat, .. }) => {
359 match (&init.hir_id, &expr.hir_id) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::None);
}
}
};assert_eq!(init.hir_id, expr.hir_id);
360 pat.is_guaranteed_to_constitute_read_for_never()
361 }
362
363 ExprKind::Array(_)
365 | ExprKind::Call(_, _)
366 | ExprKind::Use(_, _)
367 | ExprKind::MethodCall(_, _, _, _)
368 | ExprKind::Tup(_)
369 | ExprKind::Binary(_, _, _)
370 | ExprKind::Unary(_, _)
371 | ExprKind::Cast(_, _)
372 | ExprKind::DropTemps(_)
373 | ExprKind::If(_, _, _)
374 | ExprKind::Closure(_)
375 | ExprKind::Block(_, _)
376 | ExprKind::AssignOp(_, _, _)
377 | ExprKind::Index(_, _, _)
378 | ExprKind::Break(_, _)
379 | ExprKind::Ret(_)
380 | ExprKind::Become(_)
381 | ExprKind::InlineAsm(_)
382 | ExprKind::Struct(_, _, _)
383 | ExprKind::Repeat(_, _)
384 | ExprKind::Yield(_, _) => true,
385
386 ExprKind::ConstBlock(_)
388 | ExprKind::Loop(_, _, _, _)
389 | ExprKind::Lit(_)
390 | ExprKind::Path(_)
391 | ExprKind::Continue(_)
392 | ExprKind::OffsetOf(_, _)
393 | ExprKind::Err(_) => {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("no sub-expr expected for {0:?}", expr.kind)));
}unreachable!("no sub-expr expected for {:?}", expr.kind),
394 }
395 }
396
397 Node::LetStmt(LetStmt { init: Some(target), pat, .. }) => {
400 match (&target.hir_id, &expr.hir_id) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::None);
}
}
};assert_eq!(target.hir_id, expr.hir_id);
401 pat.is_guaranteed_to_constitute_read_for_never()
402 }
403
404 Node::Block(_)
406 | Node::Arm(_)
407 | Node::ExprField(_)
408 | Node::AnonConst(_)
409 | Node::ConstBlock(_)
410 | Node::ConstArg(_)
411 | Node::Stmt(_)
412 | Node::Item(Item { kind: ItemKind::Const(..) | ItemKind::Static(..), .. })
413 | Node::TraitItem(TraitItem { kind: TraitItemKind::Const(..), .. })
414 | Node::ImplItem(ImplItem { kind: ImplItemKind::Const(..), .. }) => true,
415
416 Node::TyPat(_) | Node::Pat(_) => {
417 self.dcx().span_delayed_bug(expr.span, "place expr not allowed in pattern");
418 true
419 }
420
421 Node::Param(_)
423 | Node::Item(_)
424 | Node::ForeignItem(_)
425 | Node::TraitItem(_)
426 | Node::ImplItem(_)
427 | Node::Variant(_)
428 | Node::Field(_)
429 | Node::PathSegment(_)
430 | Node::Ty(_)
431 | Node::AssocItemConstraint(_)
432 | Node::TraitRef(_)
433 | Node::PatField(_)
434 | Node::PatExpr(_)
435 | Node::LetStmt(_)
436 | Node::Synthetic
437 | Node::Err(_)
438 | Node::Ctor(_)
439 | Node::Lifetime(_)
440 | Node::GenericParam(_)
441 | Node::Crate(_)
442 | Node::Infer(_)
443 | Node::WherePredicate(_)
444 | Node::PreciseCapturingNonLifetimeArg(_)
445 | Node::ConstArgExprField(_)
446 | Node::OpaqueTy(_) => {
447 {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("no sub-expr expected for {0:?}", parent_node)));
}unreachable!("no sub-expr expected for {parent_node:?}")
448 }
449 }
450 }
451
452 #[inline]
453 fn hir_owner_parent_impl(self, owner_id: OwnerId) -> HirId {
454 self.opt_local_parent(owner_id.def_id).map_or(CRATE_HIR_ID, |parent_def_id| {
455 let parent_owner_id = self.local_def_id_to_hir_id(parent_def_id).owner;
456 HirId {
457 owner: parent_owner_id,
458 local_id: self
459 .hir_crate(())
460 .owner(self, parent_owner_id.def_id)
461 .unwrap()
462 .parenting
463 .get(&owner_id.def_id)
464 .copied()
465 .unwrap_or(ItemLocalId::ZERO),
466 }
467 })
468 }
469
470 #[inline]
473 pub fn hir_owner_parent(self, owner_id: OwnerId) -> HirId {
474 if self.dep_graph.is_fully_enabled() {
475 self.hir_owner_parent_q(owner_id)
476 } else {
477 self.hir_owner_parent_impl(owner_id)
478 }
479 }
480}
481
482#[derive(#[automatically_derived]
impl ::core::clone::Clone for Hashes {
#[inline]
fn clone(&self) -> Hashes {
let _: ::core::clone::AssertParamIsClone<Option<Fingerprint>>;
let _: ::core::clone::AssertParamIsClone<Option<Fingerprint>>;
let _: ::core::clone::AssertParamIsClone<Option<Fingerprint>>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Hashes { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for Hashes {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f, "Hashes",
"opt_hash_including_bodies", &self.opt_hash_including_bodies,
"attrs_hash", &self.attrs_hash, "delayed_lints_hash",
&&self.delayed_lints_hash)
}
}Debug)]
484pub struct Hashes {
485 pub opt_hash_including_bodies: Option<Fingerprint>,
486 pub attrs_hash: Option<Fingerprint>,
487 pub delayed_lints_hash: Option<Fingerprint>,
488}
489
490pub fn provide(providers: &mut Providers) {
491 providers.hir_crate_items = map::hir_crate_items;
492 providers.crate_hash = map::crate_hash;
493 providers.hir_module_items = map::hir_module_items;
494 providers.local_def_id_to_hir_id = |tcx, def_id| match tcx.hir_crate(()).owner(tcx, def_id) {
495 MaybeOwner::Owner(_) => HirId::make_owner(def_id),
496 MaybeOwner::NonOwner(hir_id) => hir_id,
497 MaybeOwner::Phantom => crate::util::bug::bug_fmt(format_args!("no HirId for {0:?}", def_id))bug!("no HirId for {:?}", def_id),
498 MaybeOwner::Delayed(_) => crate::util::bug::bug_fmt(format_args!("delayed owner should be lowered {0:?}",
def_id))bug!("delayed owner should be lowered {:?}", def_id),
499 };
500 providers.opt_hir_owner_nodes =
501 |tcx, id| tcx.hir_crate(()).owner(tcx, id).as_owner().map(|i| &i.nodes);
502 providers.hir_owner_parent_q = |tcx, owner_id| tcx.hir_owner_parent_impl(owner_id);
503 providers.hir_attr_map = |tcx, id| {
504 tcx.hir_crate(()).owner(tcx, id.def_id).as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs)
505 };
506 providers.opt_ast_lowering_delayed_lints =
507 |tcx, id| tcx.hir_crate(()).owner(tcx, id.def_id).as_owner().map(|o| &o.delayed_lints);
508 providers.def_span = |tcx, def_id| tcx.hir_span(tcx.local_def_id_to_hir_id(def_id));
509 providers.def_ident_span = |tcx, def_id| {
510 let hir_id = tcx.local_def_id_to_hir_id(def_id);
511 tcx.hir_opt_ident_span(hir_id)
512 };
513 providers.ty_span = |tcx, def_id| {
514 let node = tcx.hir_node_by_def_id(def_id);
515 match node.ty() {
516 Some(ty) => ty.span,
517 None => crate::util::bug::bug_fmt(format_args!("{0:?} doesn\'t have a type: {1:#?}",
def_id, node))bug!("{def_id:?} doesn't have a type: {node:#?}"),
518 }
519 };
520 providers.fn_arg_idents = |tcx, def_id| {
521 let node = tcx.hir_node_by_def_id(def_id);
522 if let Some(body_id) = node.body_id() {
523 tcx.arena.alloc_from_iter(tcx.hir_body_param_idents(body_id))
524 } else if let Node::TraitItem(&TraitItem {
525 kind: TraitItemKind::Fn(_, TraitFn::Required(idents)),
526 ..
527 })
528 | Node::ForeignItem(&ForeignItem {
529 kind: ForeignItemKind::Fn(_, idents, _),
530 ..
531 }) = node
532 {
533 idents
534 } else {
535 crate::util::bug::span_bug_fmt(tcx.hir_span(tcx.local_def_id_to_hir_id(def_id)),
format_args!("fn_arg_idents: unexpected item {0:?}", def_id));span_bug!(
536 tcx.hir_span(tcx.local_def_id_to_hir_id(def_id)),
537 "fn_arg_idents: unexpected item {:?}",
538 def_id
539 );
540 }
541 };
542 providers.all_local_trait_impls = |tcx, ()| &tcx.resolutions(()).trait_impls;
543 providers.local_trait_impls =
544 |tcx, trait_id| tcx.resolutions(()).trait_impls.get(&trait_id).map_or(&[], |xs| &xs[..]);
545 providers.expn_that_defined =
546 |tcx, id| tcx.resolutions(()).expn_that_defined.get(&id).copied().unwrap_or(ExpnId::root());
547 providers.in_scope_traits_map = |tcx, id| {
548 tcx.hir_crate(()).owner(tcx, id.def_id).as_owner().map(|owner_info| &owner_info.trait_map)
549 };
550}