1pub mod map;
6pub mod nested_filter;
7pub mod place;
8
9use rustc_data_structures::fingerprint::Fingerprint;
10use rustc_data_structures::sorted_map::SortedMap;
11use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
12use rustc_data_structures::sync::{DynSend, DynSync, try_par_for_each_in};
13use rustc_hir::def::{DefKind, Res};
14use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
15use rustc_hir::lints::DelayedLint;
16use rustc_hir::*;
17use rustc_macros::{Decodable, Encodable, HashStable};
18use rustc_span::{ErrorGuaranteed, ExpnId, Span};
19
20use crate::query::Providers;
21use crate::ty::TyCtxt;
22
23#[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_query_system::ich::StableHashingContext<'__ctx>>
for ModuleItems {
#[inline]
fn hash_stable(&self,
__hcx:
&mut ::rustc_query_system::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)]
26pub struct ModuleItems {
27 add_root: bool,
30 submodules: Box<[OwnerId]>,
31 free_items: Box<[ItemId]>,
32 trait_items: Box<[TraitItemId]>,
33 impl_items: Box<[ImplItemId]>,
34 foreign_items: Box<[ForeignItemId]>,
35 opaques: Box<[LocalDefId]>,
36 body_owners: Box<[LocalDefId]>,
37 nested_bodies: Box<[LocalDefId]>,
38 delayed_lint_items: Box<[OwnerId]>,
40
41 eiis: Box<[LocalDefId]>,
43}
44
45impl ModuleItems {
46 pub fn free_items(&self) -> impl Iterator<Item = ItemId> {
53 self.free_items.iter().copied()
54 }
55
56 pub fn trait_items(&self) -> impl Iterator<Item = TraitItemId> {
57 self.trait_items.iter().copied()
58 }
59
60 pub fn delayed_lint_items(&self) -> impl Iterator<Item = OwnerId> {
61 self.delayed_lint_items.iter().copied()
62 }
63
64 pub fn eiis(&self) -> impl Iterator<Item = LocalDefId> {
65 self.eiis.iter().copied()
66 }
67
68 pub fn impl_items(&self) -> impl Iterator<Item = ImplItemId> {
71 self.impl_items.iter().copied()
72 }
73
74 pub fn foreign_items(&self) -> impl Iterator<Item = ForeignItemId> {
75 self.foreign_items.iter().copied()
76 }
77
78 pub fn owners(&self) -> impl Iterator<Item = OwnerId> {
79 self.add_root
80 .then_some(CRATE_OWNER_ID)
81 .into_iter()
82 .chain(self.free_items.iter().map(|id| id.owner_id))
83 .chain(self.trait_items.iter().map(|id| id.owner_id))
84 .chain(self.impl_items.iter().map(|id| id.owner_id))
85 .chain(self.foreign_items.iter().map(|id| id.owner_id))
86 }
87
88 pub fn opaques(&self) -> impl Iterator<Item = LocalDefId> {
89 self.opaques.iter().copied()
90 }
91
92 pub fn nested_bodies(&self) -> impl Iterator<Item = LocalDefId> {
94 self.nested_bodies.iter().copied()
95 }
96
97 pub fn definitions(&self) -> impl Iterator<Item = LocalDefId> {
98 self.owners().map(|id| id.def_id)
99 }
100
101 pub fn par_nested_bodies(
103 &self,
104 f: impl Fn(LocalDefId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
105 ) -> Result<(), ErrorGuaranteed> {
106 try_par_for_each_in(&self.nested_bodies[..], |&&id| f(id))
107 }
108
109 pub fn par_items(
110 &self,
111 f: impl Fn(ItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
112 ) -> Result<(), ErrorGuaranteed> {
113 try_par_for_each_in(&self.free_items[..], |&&id| f(id))
114 }
115
116 pub fn par_trait_items(
117 &self,
118 f: impl Fn(TraitItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
119 ) -> Result<(), ErrorGuaranteed> {
120 try_par_for_each_in(&self.trait_items[..], |&&id| f(id))
121 }
122
123 pub fn par_impl_items(
124 &self,
125 f: impl Fn(ImplItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
126 ) -> Result<(), ErrorGuaranteed> {
127 try_par_for_each_in(&self.impl_items[..], |&&id| f(id))
128 }
129
130 pub fn par_foreign_items(
131 &self,
132 f: impl Fn(ForeignItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
133 ) -> Result<(), ErrorGuaranteed> {
134 try_par_for_each_in(&self.foreign_items[..], |&&id| f(id))
135 }
136
137 pub fn par_opaques(
138 &self,
139 f: impl Fn(LocalDefId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
140 ) -> Result<(), ErrorGuaranteed> {
141 try_par_for_each_in(&self.opaques[..], |&&id| f(id))
142 }
143}
144
145impl<'tcx> TyCtxt<'tcx> {
146 pub fn parent_module(self, id: HirId) -> LocalModDefId {
147 if !id.is_owner() && self.def_kind(id.owner) == DefKind::Mod {
148 LocalModDefId::new_unchecked(id.owner.def_id)
149 } else {
150 self.parent_module_from_def_id(id.owner.def_id)
151 }
152 }
153
154 pub fn parent_module_from_def_id(self, mut id: LocalDefId) -> LocalModDefId {
155 while let Some(parent) = self.opt_local_parent(id) {
156 id = parent;
157 if self.def_kind(id) == DefKind::Mod {
158 break;
159 }
160 }
161 LocalModDefId::new_unchecked(id)
162 }
163
164 pub fn is_foreign_item(self, def_id: impl Into<DefId>) -> bool {
166 self.opt_parent(def_id.into())
167 .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))
168 }
169
170 pub fn hash_owner_nodes(
171 self,
172 node: OwnerNode<'_>,
173 bodies: &SortedMap<ItemLocalId, &Body<'_>>,
174 attrs: &SortedMap<ItemLocalId, &[Attribute]>,
175 delayed_lints: &[DelayedLint],
176 define_opaque: Option<&[(Span, LocalDefId)]>,
177 ) -> Hashes {
178 if !self.needs_crate_hash() {
179 return Hashes {
180 opt_hash_including_bodies: None,
181 attrs_hash: None,
182 delayed_lints_hash: None,
183 };
184 }
185
186 self.with_stable_hashing_context(|mut hcx| {
187 let mut stable_hasher = StableHasher::new();
188 node.hash_stable(&mut hcx, &mut stable_hasher);
189 bodies.hash_stable(&mut hcx, &mut stable_hasher);
191 let h1 = stable_hasher.finish();
192
193 let mut stable_hasher = StableHasher::new();
194 attrs.hash_stable(&mut hcx, &mut stable_hasher);
195
196 define_opaque.hash_stable(&mut hcx, &mut stable_hasher);
198
199 let h2 = stable_hasher.finish();
200
201 let mut stable_hasher = StableHasher::new();
203 delayed_lints.hash_stable(&mut hcx, &mut stable_hasher);
204 let h3 = stable_hasher.finish();
205
206 Hashes {
207 opt_hash_including_bodies: Some(h1),
208 attrs_hash: Some(h2),
209 delayed_lints_hash: Some(h3),
210 }
211 })
212 }
213
214 pub fn qpath_is_lang_item(self, qpath: QPath<'_>, lang_item: LangItem) -> bool {
215 self.qpath_lang_item(qpath) == Some(lang_item)
216 }
217
218 pub fn qpath_lang_item(self, qpath: QPath<'_>) -> Option<LangItem> {
220 if let QPath::Resolved(_, path) = qpath
221 && let Res::Def(_, def_id) = path.res
222 {
223 return self.lang_items().from_def_id(def_id);
224 }
225 None
226 }
227
228 pub fn expr_guaranteed_to_constitute_read_for_never(self, expr: &Expr<'_>) -> bool {
240 if !expr.is_syntactic_place_expr() {
246 return true;
247 }
248
249 let parent_node = self.parent_hir_node(expr.hir_id);
250 match parent_node {
251 Node::Expr(parent_expr) => {
252 match parent_expr.kind {
253 ExprKind::AddrOf(..) | ExprKind::Field(..) => false,
257
258 ExprKind::Type(..) | ExprKind::UnsafeBinderCast(..) => {
261 self.expr_guaranteed_to_constitute_read_for_never(parent_expr)
262 }
263
264 ExprKind::Assign(lhs, _, _) => {
265 expr.hir_id != lhs.hir_id
267 }
268
269 ExprKind::Match(scrutinee, arms, _) => {
272 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);
273 arms.iter().all(|arm| arm.pat.is_guaranteed_to_constitute_read_for_never())
274 }
275 ExprKind::Let(LetExpr { init, pat, .. }) => {
276 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);
277 pat.is_guaranteed_to_constitute_read_for_never()
278 }
279
280 ExprKind::Array(_)
282 | ExprKind::Call(_, _)
283 | ExprKind::Use(_, _)
284 | ExprKind::MethodCall(_, _, _, _)
285 | ExprKind::Tup(_)
286 | ExprKind::Binary(_, _, _)
287 | ExprKind::Unary(_, _)
288 | ExprKind::Cast(_, _)
289 | ExprKind::DropTemps(_)
290 | ExprKind::If(_, _, _)
291 | ExprKind::Closure(_)
292 | ExprKind::Block(_, _)
293 | ExprKind::AssignOp(_, _, _)
294 | ExprKind::Index(_, _, _)
295 | ExprKind::Break(_, _)
296 | ExprKind::Ret(_)
297 | ExprKind::Become(_)
298 | ExprKind::InlineAsm(_)
299 | ExprKind::Struct(_, _, _)
300 | ExprKind::Repeat(_, _)
301 | ExprKind::Yield(_, _) => true,
302
303 ExprKind::ConstBlock(_)
305 | ExprKind::Loop(_, _, _, _)
306 | ExprKind::Lit(_)
307 | ExprKind::Path(_)
308 | ExprKind::Continue(_)
309 | ExprKind::OffsetOf(_, _)
310 | 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),
311 }
312 }
313
314 Node::LetStmt(LetStmt { init: Some(target), pat, .. }) => {
317 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);
318 pat.is_guaranteed_to_constitute_read_for_never()
319 }
320
321 Node::Block(_)
323 | Node::Arm(_)
324 | Node::ExprField(_)
325 | Node::AnonConst(_)
326 | Node::ConstBlock(_)
327 | Node::ConstArg(_)
328 | Node::Stmt(_)
329 | Node::Item(Item { kind: ItemKind::Const(..) | ItemKind::Static(..), .. })
330 | Node::TraitItem(TraitItem { kind: TraitItemKind::Const(..), .. })
331 | Node::ImplItem(ImplItem { kind: ImplItemKind::Const(..), .. }) => true,
332
333 Node::TyPat(_) | Node::Pat(_) => {
334 self.dcx().span_delayed_bug(expr.span, "place expr not allowed in pattern");
335 true
336 }
337
338 Node::Param(_)
340 | Node::Item(_)
341 | Node::ForeignItem(_)
342 | Node::TraitItem(_)
343 | Node::ImplItem(_)
344 | Node::Variant(_)
345 | Node::Field(_)
346 | Node::PathSegment(_)
347 | Node::Ty(_)
348 | Node::AssocItemConstraint(_)
349 | Node::TraitRef(_)
350 | Node::PatField(_)
351 | Node::PatExpr(_)
352 | Node::LetStmt(_)
353 | Node::Synthetic
354 | Node::Err(_)
355 | Node::Ctor(_)
356 | Node::Lifetime(_)
357 | Node::GenericParam(_)
358 | Node::Crate(_)
359 | Node::Infer(_)
360 | Node::WherePredicate(_)
361 | Node::PreciseCapturingNonLifetimeArg(_)
362 | Node::ConstArgExprField(_)
363 | Node::OpaqueTy(_) => {
364 {
::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:?}")
365 }
366 }
367 }
368
369 #[inline]
370 fn hir_owner_parent_impl(self, owner_id: OwnerId) -> HirId {
371 self.opt_local_parent(owner_id.def_id).map_or(CRATE_HIR_ID, |parent_def_id| {
372 let parent_owner_id = self.local_def_id_to_hir_id(parent_def_id).owner;
373 HirId {
374 owner: parent_owner_id,
375 local_id: self.hir_crate(()).owners[parent_owner_id.def_id]
376 .unwrap()
377 .parenting
378 .get(&owner_id.def_id)
379 .copied()
380 .unwrap_or(ItemLocalId::ZERO),
381 }
382 })
383 }
384
385 #[inline]
388 pub fn hir_owner_parent(self, owner_id: OwnerId) -> HirId {
389 if self.dep_graph.is_fully_enabled() {
390 self.hir_owner_parent_q(owner_id)
391 } else {
392 self.hir_owner_parent_impl(owner_id)
393 }
394 }
395}
396
397#[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)]
399pub struct Hashes {
400 pub opt_hash_including_bodies: Option<Fingerprint>,
401 pub attrs_hash: Option<Fingerprint>,
402 pub delayed_lints_hash: Option<Fingerprint>,
403}
404
405pub fn provide(providers: &mut Providers) {
406 providers.hir_crate_items = map::hir_crate_items;
407 providers.crate_hash = map::crate_hash;
408 providers.hir_module_items = map::hir_module_items;
409 providers.local_def_id_to_hir_id = |tcx, def_id| match tcx.hir_crate(()).owners[def_id] {
410 MaybeOwner::Owner(_) => HirId::make_owner(def_id),
411 MaybeOwner::NonOwner(hir_id) => hir_id,
412 MaybeOwner::Phantom => crate::util::bug::bug_fmt(format_args!("No HirId for {0:?}", def_id))bug!("No HirId for {:?}", def_id),
413 };
414 providers.opt_hir_owner_nodes =
415 |tcx, id| tcx.hir_crate(()).owners.get(id)?.as_owner().map(|i| &i.nodes);
416 providers.hir_owner_parent_q = |tcx, owner_id| tcx.hir_owner_parent_impl(owner_id);
417 providers.hir_attr_map = |tcx, id| {
418 tcx.hir_crate(()).owners[id.def_id].as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs)
419 };
420 providers.opt_ast_lowering_delayed_lints =
421 |tcx, id| tcx.hir_crate(()).owners[id.def_id].as_owner().map(|o| &o.delayed_lints);
422 providers.def_span = |tcx, def_id| tcx.hir_span(tcx.local_def_id_to_hir_id(def_id));
423 providers.def_ident_span = |tcx, def_id| {
424 let hir_id = tcx.local_def_id_to_hir_id(def_id);
425 tcx.hir_opt_ident_span(hir_id)
426 };
427 providers.ty_span = |tcx, def_id| {
428 let node = tcx.hir_node_by_def_id(def_id);
429 match node.ty() {
430 Some(ty) => ty.span,
431 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:#?}"),
432 }
433 };
434 providers.fn_arg_idents = |tcx, def_id| {
435 let node = tcx.hir_node_by_def_id(def_id);
436 if let Some(body_id) = node.body_id() {
437 tcx.arena.alloc_from_iter(tcx.hir_body_param_idents(body_id))
438 } else if let Node::TraitItem(&TraitItem {
439 kind: TraitItemKind::Fn(_, TraitFn::Required(idents)),
440 ..
441 })
442 | Node::ForeignItem(&ForeignItem {
443 kind: ForeignItemKind::Fn(_, idents, _),
444 ..
445 }) = node
446 {
447 idents
448 } else {
449 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!(
450 tcx.hir_span(tcx.local_def_id_to_hir_id(def_id)),
451 "fn_arg_idents: unexpected item {:?}",
452 def_id
453 );
454 }
455 };
456 providers.all_local_trait_impls = |tcx, ()| &tcx.resolutions(()).trait_impls;
457 providers.local_trait_impls =
458 |tcx, trait_id| tcx.resolutions(()).trait_impls.get(&trait_id).map_or(&[], |xs| &xs[..]);
459 providers.expn_that_defined =
460 |tcx, id| tcx.resolutions(()).expn_that_defined.get(&id).copied().unwrap_or(ExpnId::root());
461 providers.in_scope_traits_map = |tcx, id| {
462 tcx.hir_crate(()).owners[id.def_id].as_owner().map(|owner_info| &owner_info.trait_map)
463 };
464}