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;
14use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
15use rustc_hir::*;
16use rustc_macros::{Decodable, Encodable, HashStable};
17use rustc_span::{ErrorGuaranteed, ExpnId, Span};
18
19use crate::query::Providers;
20use crate::ty::{EarlyBinder, ImplSubject, TyCtxt};
21
22#[derive(Debug, HashStable, Encodable, Decodable)]
25pub struct ModuleItems {
26 submodules: Box<[OwnerId]>,
27 free_items: Box<[ItemId]>,
28 trait_items: Box<[TraitItemId]>,
29 impl_items: Box<[ImplItemId]>,
30 foreign_items: Box<[ForeignItemId]>,
31 opaques: Box<[LocalDefId]>,
32 body_owners: Box<[LocalDefId]>,
33 nested_bodies: Box<[LocalDefId]>,
34}
35
36impl ModuleItems {
37 pub fn free_items(&self) -> impl Iterator<Item = ItemId> {
44 self.free_items.iter().copied()
45 }
46
47 pub fn trait_items(&self) -> impl Iterator<Item = TraitItemId> {
48 self.trait_items.iter().copied()
49 }
50
51 pub fn impl_items(&self) -> impl Iterator<Item = ImplItemId> {
54 self.impl_items.iter().copied()
55 }
56
57 pub fn foreign_items(&self) -> impl Iterator<Item = ForeignItemId> {
58 self.foreign_items.iter().copied()
59 }
60
61 pub fn owners(&self) -> impl Iterator<Item = OwnerId> {
62 self.free_items
63 .iter()
64 .map(|id| id.owner_id)
65 .chain(self.trait_items.iter().map(|id| id.owner_id))
66 .chain(self.impl_items.iter().map(|id| id.owner_id))
67 .chain(self.foreign_items.iter().map(|id| id.owner_id))
68 }
69
70 pub fn opaques(&self) -> impl Iterator<Item = LocalDefId> {
71 self.opaques.iter().copied()
72 }
73
74 pub fn nested_bodies(&self) -> impl Iterator<Item = LocalDefId> {
75 self.nested_bodies.iter().copied()
76 }
77
78 pub fn definitions(&self) -> impl Iterator<Item = LocalDefId> {
79 self.owners().map(|id| id.def_id)
80 }
81
82 pub fn par_items(
83 &self,
84 f: impl Fn(ItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
85 ) -> Result<(), ErrorGuaranteed> {
86 try_par_for_each_in(&self.free_items[..], |&id| f(id))
87 }
88
89 pub fn par_trait_items(
90 &self,
91 f: impl Fn(TraitItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
92 ) -> Result<(), ErrorGuaranteed> {
93 try_par_for_each_in(&self.trait_items[..], |&id| f(id))
94 }
95
96 pub fn par_impl_items(
97 &self,
98 f: impl Fn(ImplItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
99 ) -> Result<(), ErrorGuaranteed> {
100 try_par_for_each_in(&self.impl_items[..], |&id| f(id))
101 }
102
103 pub fn par_foreign_items(
104 &self,
105 f: impl Fn(ForeignItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
106 ) -> Result<(), ErrorGuaranteed> {
107 try_par_for_each_in(&self.foreign_items[..], |&id| f(id))
108 }
109
110 pub fn par_opaques(
111 &self,
112 f: impl Fn(LocalDefId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
113 ) -> Result<(), ErrorGuaranteed> {
114 try_par_for_each_in(&self.opaques[..], |&id| f(id))
115 }
116}
117
118impl<'tcx> TyCtxt<'tcx> {
119 #[inline(always)]
120 pub fn hir(self) -> map::Map<'tcx> {
121 map::Map { tcx: self }
122 }
123
124 pub fn parent_module(self, id: HirId) -> LocalModDefId {
125 if !id.is_owner() && self.def_kind(id.owner) == DefKind::Mod {
126 LocalModDefId::new_unchecked(id.owner.def_id)
127 } else {
128 self.parent_module_from_def_id(id.owner.def_id)
129 }
130 }
131
132 pub fn parent_module_from_def_id(self, mut id: LocalDefId) -> LocalModDefId {
133 while let Some(parent) = self.opt_local_parent(id) {
134 id = parent;
135 if self.def_kind(id) == DefKind::Mod {
136 break;
137 }
138 }
139 LocalModDefId::new_unchecked(id)
140 }
141
142 pub fn impl_subject(self, def_id: DefId) -> EarlyBinder<'tcx, ImplSubject<'tcx>> {
143 match self.impl_trait_ref(def_id) {
144 Some(t) => t.map_bound(ImplSubject::Trait),
145 None => self.type_of(def_id).map_bound(ImplSubject::Inherent),
146 }
147 }
148
149 pub fn is_foreign_item(self, def_id: impl Into<DefId>) -> bool {
151 self.opt_parent(def_id.into())
152 .is_some_and(|parent| matches!(self.def_kind(parent), DefKind::ForeignMod))
153 }
154
155 pub fn hash_owner_nodes(
156 self,
157 node: OwnerNode<'_>,
158 bodies: &SortedMap<ItemLocalId, &Body<'_>>,
159 attrs: &SortedMap<ItemLocalId, &[Attribute]>,
160 define_opaque: Option<&[(Span, LocalDefId)]>,
161 ) -> (Option<Fingerprint>, Option<Fingerprint>) {
162 if self.needs_crate_hash() {
163 self.with_stable_hashing_context(|mut hcx| {
164 let mut stable_hasher = StableHasher::new();
165 node.hash_stable(&mut hcx, &mut stable_hasher);
166 bodies.hash_stable(&mut hcx, &mut stable_hasher);
168 let h1 = stable_hasher.finish();
169
170 let mut stable_hasher = StableHasher::new();
171 attrs.hash_stable(&mut hcx, &mut stable_hasher);
172
173 define_opaque.hash_stable(&mut hcx, &mut stable_hasher);
175
176 let h2 = stable_hasher.finish();
177 (Some(h1), Some(h2))
178 })
179 } else {
180 (None, None)
181 }
182 }
183}
184
185pub fn provide(providers: &mut Providers) {
186 providers.hir_crate_items = map::hir_crate_items;
187 providers.crate_hash = map::crate_hash;
188 providers.hir_module_items = map::hir_module_items;
189 providers.local_def_id_to_hir_id = |tcx, def_id| match tcx.hir_crate(()).owners[def_id] {
190 MaybeOwner::Owner(_) => HirId::make_owner(def_id),
191 MaybeOwner::NonOwner(hir_id) => hir_id,
192 MaybeOwner::Phantom => bug!("No HirId for {:?}", def_id),
193 };
194 providers.opt_hir_owner_nodes =
195 |tcx, id| tcx.hir_crate(()).owners.get(id)?.as_owner().map(|i| &i.nodes);
196 providers.hir_owner_parent = |tcx, owner_id| {
197 tcx.opt_local_parent(owner_id.def_id).map_or(CRATE_HIR_ID, |parent_def_id| {
198 let parent_owner_id = tcx.local_def_id_to_hir_id(parent_def_id).owner;
199 HirId {
200 owner: parent_owner_id,
201 local_id: tcx.hir_crate(()).owners[parent_owner_id.def_id]
202 .unwrap()
203 .parenting
204 .get(&owner_id.def_id)
205 .copied()
206 .unwrap_or(ItemLocalId::ZERO),
207 }
208 })
209 };
210 providers.hir_attr_map = |tcx, id| {
211 tcx.hir_crate(()).owners[id.def_id].as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs)
212 };
213 providers.def_span = |tcx, def_id| tcx.hir().span(tcx.local_def_id_to_hir_id(def_id));
214 providers.def_ident_span = |tcx, def_id| {
215 let hir_id = tcx.local_def_id_to_hir_id(def_id);
216 tcx.hir_opt_ident_span(hir_id)
217 };
218 providers.fn_arg_names = |tcx, def_id| {
219 let hir = tcx.hir();
220 if let Some(body_id) = tcx.hir_node_by_def_id(def_id).body_id() {
221 tcx.arena.alloc_from_iter(tcx.hir_body_param_names(body_id))
222 } else if let Node::TraitItem(&TraitItem {
223 kind: TraitItemKind::Fn(_, TraitFn::Required(idents)),
224 ..
225 })
226 | Node::ForeignItem(&ForeignItem {
227 kind: ForeignItemKind::Fn(_, idents, _),
228 ..
229 }) = tcx.hir_node(tcx.local_def_id_to_hir_id(def_id))
230 {
231 idents
232 } else {
233 span_bug!(
234 hir.span(tcx.local_def_id_to_hir_id(def_id)),
235 "fn_arg_names: unexpected item {:?}",
236 def_id
237 );
238 }
239 };
240 providers.all_local_trait_impls = |tcx, ()| &tcx.resolutions(()).trait_impls;
241 providers.expn_that_defined =
242 |tcx, id| tcx.resolutions(()).expn_that_defined.get(&id).copied().unwrap_or(ExpnId::root());
243 providers.in_scope_traits_map = |tcx, id| {
244 tcx.hir_crate(()).owners[id.def_id].as_owner().map(|owner_info| &owner_info.trait_map)
245 };
246}