1use std::any::Any;
2use std::mem;
3use std::sync::Arc;
4
5use rustc_hir::attrs::Deprecation;
6use rustc_hir::def::{CtorKind, DefKind};
7use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE};
8use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
9use rustc_middle::arena::ArenaAllocatable;
10use rustc_middle::bug;
11use rustc_middle::metadata::{AmbigModChild, ModChild};
12use rustc_middle::middle::exported_symbols::ExportedSymbol;
13use rustc_middle::middle::stability::DeprecationEntry;
14use rustc_middle::query::{ExternProviders, LocalCrate};
15use rustc_middle::ty::fast_reject::SimplifiedType;
16use rustc_middle::ty::{self, TyCtxt};
17use rustc_middle::util::Providers;
18use rustc_serialize::Decoder;
19use rustc_session::StableCrateId;
20use rustc_session::cstore::{CrateStore, ExternCrate};
21use rustc_span::hygiene::ExpnId;
22use rustc_span::{Span, Symbol, kw};
23
24use super::{Decodable, DecodeIterator};
25use crate::creader::{CStore, LoadedMacro};
26use crate::rmeta::AttrFlags;
27use crate::rmeta::table::IsDefault;
28use crate::{eii, foreign_modules, native_libs};
29
30trait ProcessQueryValue<'tcx, T> {
31 fn process_decoded(self, _tcx: TyCtxt<'tcx>, _err: impl Fn() -> !) -> T;
32}
33
34impl<T> ProcessQueryValue<'_, T> for T {
35 #[inline(always)]
36 fn process_decoded(self, _tcx: TyCtxt<'_>, _err: impl Fn() -> !) -> T {
37 self
38 }
39}
40
41impl<'tcx, T> ProcessQueryValue<'tcx, ty::EarlyBinder<'tcx, T>> for T {
42 #[inline(always)]
43 fn process_decoded(self, _tcx: TyCtxt<'_>, _err: impl Fn() -> !) -> ty::EarlyBinder<'tcx, T> {
44 ty::EarlyBinder::bind(self)
45 }
46}
47
48impl<T> ProcessQueryValue<'_, T> for Option<T> {
49 #[inline(always)]
50 fn process_decoded(self, _tcx: TyCtxt<'_>, err: impl Fn() -> !) -> T {
51 if let Some(value) = self { value } else { err() }
52 }
53}
54
55impl<'tcx, T: ArenaAllocatable<'tcx>> ProcessQueryValue<'tcx, &'tcx T> for Option<T> {
56 #[inline(always)]
57 fn process_decoded(self, tcx: TyCtxt<'tcx>, err: impl Fn() -> !) -> &'tcx T {
58 if let Some(value) = self { tcx.arena.alloc(value) } else { err() }
59 }
60}
61
62impl<T, E> ProcessQueryValue<'_, Result<Option<T>, E>> for Option<T> {
63 #[inline(always)]
64 fn process_decoded(self, _tcx: TyCtxt<'_>, _err: impl Fn() -> !) -> Result<Option<T>, E> {
65 Ok(self)
66 }
67}
68
69impl<'tcx, D: Decoder, T: Copy + Decodable<D>> ProcessQueryValue<'tcx, &'tcx [T]>
70 for Option<DecodeIterator<T, D>>
71{
72 #[inline(always)]
73 fn process_decoded(self, tcx: TyCtxt<'tcx>, err: impl Fn() -> !) -> &'tcx [T] {
74 if let Some(iter) = self { tcx.arena.alloc_from_iter(iter) } else { err() }
75 }
76}
77
78impl<'tcx, D: Decoder, T: Copy + Decodable<D>> ProcessQueryValue<'tcx, Option<&'tcx [T]>>
79 for Option<DecodeIterator<T, D>>
80{
81 #[inline(always)]
82 fn process_decoded(self, tcx: TyCtxt<'tcx>, _err: impl Fn() -> !) -> Option<&'tcx [T]> {
83 if let Some(iter) = self { Some(&*tcx.arena.alloc_from_iter(iter)) } else { None }
84 }
85}
86
87impl ProcessQueryValue<'_, Option<DeprecationEntry>> for Option<Deprecation> {
88 #[inline(always)]
89 fn process_decoded(self, _tcx: TyCtxt<'_>, _err: impl Fn() -> !) -> Option<DeprecationEntry> {
90 self.map(DeprecationEntry::external)
91 }
92}
93
94macro_rules! provide_one {
95 ($tcx:ident, $def_id:ident, $other:ident, $cdata:ident, $name:ident => { table }) => {
96 provide_one! {
97 $tcx, $def_id, $other, $cdata, $name => {
98 $cdata
99 .root
100 .tables
101 .$name
102 .get(($cdata, $tcx), $def_id.index)
103 .map(|lazy| lazy.decode(($cdata, $tcx)))
104 .process_decoded($tcx, || panic!("{:?} does not have a {:?}", $def_id, stringify!($name)))
105 }
106 }
107 };
108 ($tcx:ident, $def_id:ident, $other:ident, $cdata:ident, $name:ident => { table_defaulted_array }) => {
109 provide_one! {
110 $tcx, $def_id, $other, $cdata, $name => {
111 let lazy = $cdata.root.tables.$name.get(($cdata, $tcx), $def_id.index);
112 let value = if lazy.is_default() {
113 &[] as &[_]
114 } else {
115 $tcx.arena.alloc_from_iter(lazy.decode(($cdata, $tcx)))
116 };
117 value.process_decoded($tcx, || panic!("{:?} does not have a {:?}", $def_id, stringify!($name)))
118 }
119 }
120 };
121 ($tcx:ident, $def_id:ident, $other:ident, $cdata:ident, $name:ident => { table_direct }) => {
122 provide_one! {
123 $tcx, $def_id, $other, $cdata, $name => {
124 $cdata
126 .root
127 .tables
128 .$name
129 .get(($cdata, $tcx), $def_id.index)
130 .process_decoded($tcx, || panic!("{:?} does not have a {:?}", $def_id, stringify!($name)))
131 }
132 }
133 };
134 ($tcx:ident, $def_id:ident, $other:ident, $cdata:ident, $name:ident => $compute:block) => {
135 fn $name<'tcx>(
136 $tcx: TyCtxt<'tcx>,
137 def_id_arg: rustc_middle::query::queries::$name::Key<'tcx>,
138 ) -> rustc_middle::query::queries::$name::ProvidedValue<'tcx> {
139 let _prof_timer =
140 $tcx.prof.generic_activity(concat!("metadata_decode_entry_", stringify!($name)));
141
142 #[allow(unused_variables)]
143 let ($def_id, $other) = def_id_arg.into_args();
144 assert!(!$def_id.is_local());
145
146 use rustc_middle::dep_graph::dep_kinds;
150 if dep_kinds::$name != dep_kinds::crate_hash && $tcx.dep_graph.is_fully_enabled() {
151 $tcx.ensure_ok().crate_hash($def_id.krate);
152 }
153
154 let cdata = rustc_data_structures::sync::FreezeReadGuard::map(CStore::from_tcx($tcx), |c| {
155 c.get_crate_data($def_id.krate).cdata
156 });
157 let $cdata = crate::creader::CrateMetadataRef {
158 cdata: &cdata,
159 cstore: &CStore::from_tcx($tcx),
160 };
161
162 $compute
163 }
164 };
165}
166
167macro_rules! provide {
168 ($tcx:ident, $def_id:ident, $other:ident, $cdata:ident,
169 $($name:ident => { $($compute:tt)* })*) => {
170 fn provide_extern(providers: &mut ExternProviders) {
171 $(provide_one! {
172 $tcx, $def_id, $other, $cdata, $name => { $($compute)* }
173 })*
174
175 *providers = ExternProviders {
176 $($name,)*
177 ..*providers
178 };
179 }
180 }
181}
182
183trait IntoArgs {
186 type Other;
187 fn into_args(self) -> (DefId, Self::Other);
188}
189
190impl IntoArgs for DefId {
191 type Other = ();
192 fn into_args(self) -> (DefId, ()) {
193 (self, ())
194 }
195}
196
197impl IntoArgs for CrateNum {
198 type Other = ();
199 fn into_args(self) -> (DefId, ()) {
200 (self.as_def_id(), ())
201 }
202}
203
204impl IntoArgs for (CrateNum, DefId) {
205 type Other = DefId;
206 fn into_args(self) -> (DefId, DefId) {
207 (self.0.as_def_id(), self.1)
208 }
209}
210
211impl<'tcx> IntoArgs for ty::InstanceKind<'tcx> {
212 type Other = ();
213 fn into_args(self) -> (DefId, ()) {
214 (self.def_id(), ())
215 }
216}
217
218impl IntoArgs for (CrateNum, SimplifiedType) {
219 type Other = SimplifiedType;
220 fn into_args(self) -> (DefId, SimplifiedType) {
221 (self.0.as_def_id(), self.1)
222 }
223}
224
225provide! { tcx, def_id, other, cdata,
226 explicit_item_bounds => { table_defaulted_array }
227 explicit_item_self_bounds => { table_defaulted_array }
228 explicit_predicates_of => { table }
229 generics_of => { table }
230 inferred_outlives_of => { table_defaulted_array }
231 explicit_super_predicates_of => { table_defaulted_array }
232 explicit_implied_predicates_of => { table_defaulted_array }
233 type_of => { table }
234 type_alias_is_lazy => { table_direct }
235 variances_of => { table }
236 fn_sig => { table }
237 codegen_fn_attrs => { table }
238 impl_trait_header => { table }
239 const_param_default => { table }
240 object_lifetime_default => { table }
241 thir_abstract_const => { table }
242 optimized_mir => { table }
243 mir_for_ctfe => { table }
244 trivial_const => { table }
245 closure_saved_names_of_captured_variables => { table }
246 mir_coroutine_witnesses => { table }
247 promoted_mir => { table }
248 def_span => { table }
249 def_ident_span => { table }
250 lookup_stability => { table }
251 lookup_const_stability => { table }
252 lookup_default_body_stability => { table }
253 lookup_deprecation_entry => { table }
254 params_in_repr => { table }
255 def_kind => { cdata.def_kind(tcx, def_id.index) }
256 impl_parent => { table }
257 defaultness => { table_direct }
258 constness => { table_direct }
259 const_conditions => { table }
260 explicit_implied_const_bounds => { table_defaulted_array }
261 coerce_unsized_info => {
262 Ok(cdata
263 .root
264 .tables
265 .coerce_unsized_info
266 .get((cdata, tcx), def_id.index)
267 .map(|lazy| lazy.decode((cdata, tcx)))
268 .process_decoded(tcx, || panic!("{def_id:?} does not have coerce_unsized_info"))) }
269 mir_const_qualif => { table }
270 rendered_const => { table }
271 rendered_precise_capturing_args => { table }
272 asyncness => { table_direct }
273 fn_arg_idents => { table }
274 coroutine_kind => { table_direct }
275 coroutine_for_closure => { table }
276 coroutine_by_move_body_def_id => { table }
277 eval_static_initializer => {
278 Ok(cdata
279 .root
280 .tables
281 .eval_static_initializer
282 .get((cdata, tcx), def_id.index)
283 .map(|lazy| lazy.decode((cdata, tcx)))
284 .unwrap_or_else(|| panic!("{def_id:?} does not have eval_static_initializer")))
285 }
286 trait_def => { table }
287 deduced_param_attrs => {
288 cdata
292 .root
293 .tables
294 .deduced_param_attrs
295 .get((cdata, tcx), def_id.index)
296 .map(|lazy| {
297 &*tcx.arena.alloc_from_iter(lazy.decode((cdata, tcx)))
298 })
299 .unwrap_or_default()
300 }
301 opaque_ty_origin => { table }
302 assumed_wf_types_for_rpitit => { table }
303 collect_return_position_impl_trait_in_trait_tys => {
304 Ok(cdata
305 .root
306 .tables
307 .trait_impl_trait_tys
308 .get((cdata, tcx), def_id.index)
309 .map(|lazy| lazy.decode((cdata, tcx)))
310 .process_decoded(tcx, || panic!("{def_id:?} does not have trait_impl_trait_tys")))
311 }
312
313 associated_types_for_impl_traits_in_trait_or_impl => { table }
314
315 visibility => { cdata.get_visibility(tcx, def_id.index) }
316 adt_def => { cdata.get_adt_def(tcx, def_id.index) }
317 adt_destructor => { table }
318 adt_async_destructor => { table }
319 associated_item_def_ids => {
320 tcx.arena.alloc_from_iter(cdata.get_associated_item_or_field_def_ids(tcx, def_id.index))
321 }
322 associated_item => { cdata.get_associated_item(tcx, def_id.index) }
323 inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }
324 attrs_for_def => { tcx.arena.alloc_from_iter(cdata.get_item_attrs(tcx, def_id.index)) }
325 is_mir_available => { cdata.is_item_mir_available(tcx, def_id.index) }
326 is_ctfe_mir_available => { cdata.is_ctfe_mir_available(tcx, def_id.index) }
327 cross_crate_inlinable => { table_direct }
328
329 dylib_dependency_formats => { cdata.get_dylib_dependency_formats(tcx) }
330 is_private_dep => { cdata.private_dep }
331 is_panic_runtime => { cdata.root.panic_runtime }
332 is_compiler_builtins => { cdata.root.compiler_builtins }
333
334 has_global_allocator => { cdata.root.has_global_allocator }
336 has_alloc_error_handler => { cdata.root.has_alloc_error_handler }
338 has_panic_handler => { cdata.root.has_panic_handler }
340
341 externally_implementable_items => {
342 cdata.get_externally_implementable_items(tcx)
343 .map(|(decl_did, (decl, impls))| (
344 decl_did,
345 (decl, impls.into_iter().collect())
346 )).collect()
347 }
348
349 is_profiler_runtime => { cdata.root.profiler_runtime }
350 required_panic_strategy => { cdata.root.required_panic_strategy }
351 panic_in_drop_strategy => { cdata.root.panic_in_drop_strategy }
352 extern_crate => { cdata.extern_crate.map(|c| &*tcx.arena.alloc(c)) }
353 is_no_builtins => { cdata.root.no_builtins }
354 symbol_mangling_version => { cdata.root.symbol_mangling_version }
355 specialization_enabled_in => { cdata.root.specialization_enabled_in }
356 reachable_non_generics => {
357 let reachable_non_generics = tcx
358 .exported_non_generic_symbols(cdata.cnum)
359 .iter()
360 .filter_map(|&(exported_symbol, export_info)| {
361 if let ExportedSymbol::NonGeneric(def_id) = exported_symbol {
362 Some((def_id, export_info))
363 } else {
364 None
365 }
366 })
367 .collect();
368
369 reachable_non_generics
370 }
371 native_libraries => { cdata.get_native_libraries(tcx).collect() }
372 foreign_modules => { cdata.get_foreign_modules(tcx).map(|m| (m.def_id, m)).collect() }
373 crate_hash => { cdata.root.header.hash }
374 crate_host_hash => { cdata.host_hash }
375 crate_name => { cdata.root.header.name }
376 num_extern_def_ids => { cdata.num_def_ids() }
377
378 extra_filename => { cdata.root.extra_filename.clone() }
379
380 traits => { tcx.arena.alloc_from_iter(cdata.get_traits(tcx)) }
381 trait_impls_in_crate => { tcx.arena.alloc_from_iter(cdata.get_trait_impls(tcx)) }
382 implementations_of_trait => { cdata.get_implementations_of_trait(tcx, other) }
383 crate_incoherent_impls => { cdata.get_incoherent_impls(tcx, other) }
384
385 dep_kind => { cdata.dep_kind }
386 module_children => {
387 tcx.arena.alloc_from_iter(cdata.get_module_children(tcx, def_id.index))
388 }
389 lib_features => { cdata.get_lib_features(tcx) }
390 stability_implications => {
391 cdata.get_stability_implications(tcx).iter().copied().collect()
392 }
393 stripped_cfg_items => { cdata.get_stripped_cfg_items(tcx, cdata.cnum) }
394 intrinsic_raw => { cdata.get_intrinsic(tcx, def_id.index) }
395 defined_lang_items => { cdata.get_lang_items(tcx) }
396 diagnostic_items => { cdata.get_diagnostic_items(tcx) }
397 missing_lang_items => { cdata.get_missing_lang_items(tcx) }
398
399 missing_extern_crate_item => {
400 matches!(cdata.extern_crate, Some(extern_crate) if !extern_crate.is_direct())
401 }
402
403 used_crate_source => { Arc::clone(&cdata.source) }
404 debugger_visualizers => { cdata.get_debugger_visualizers(tcx) }
405
406 exportable_items => { tcx.arena.alloc_from_iter(cdata.get_exportable_items(tcx)) }
407 stable_order_of_exportable_impls => { tcx.arena.alloc(cdata.get_stable_order_of_exportable_impls(tcx).collect()) }
408 exported_non_generic_symbols => { cdata.exported_non_generic_symbols(tcx) }
409 exported_generic_symbols => { cdata.exported_generic_symbols(tcx) }
410
411 crate_extern_paths => { cdata.source().paths().cloned().collect() }
412 expn_that_defined => { cdata.get_expn_that_defined(tcx, def_id.index) }
413 default_field => { cdata.get_default_field(tcx, def_id.index) }
414 is_doc_hidden => { cdata.get_attr_flags(tcx,def_id.index).contains(AttrFlags::IS_DOC_HIDDEN) }
415 doc_link_resolutions => { tcx.arena.alloc(cdata.get_doc_link_resolutions(tcx, def_id.index)) }
416 doc_link_traits_in_scope => {
417 tcx.arena.alloc_from_iter(cdata.get_doc_link_traits_in_scope(tcx, def_id.index))
418 }
419 anon_const_kind => { table }
420 const_of_item => { table }
421}
422
423pub(in crate::rmeta) fn provide(providers: &mut Providers) {
424 provide_cstore_hooks(providers);
425 providers.queries = rustc_middle::query::Providers {
426 allocator_kind: |tcx, ()| CStore::from_tcx(tcx).allocator_kind(),
427 alloc_error_handler_kind: |tcx, ()| CStore::from_tcx(tcx).alloc_error_handler_kind(),
428 is_private_dep: |_tcx, LocalCrate| false,
429 native_library: |tcx, id| {
430 tcx.native_libraries(id.krate)
431 .iter()
432 .filter(|lib| native_libs::relevant_lib(tcx.sess, lib))
433 .find(|lib| {
434 let Some(fm_id) = lib.foreign_module else {
435 return false;
436 };
437 let map = tcx.foreign_modules(id.krate);
438 map.get(&fm_id)
439 .expect("failed to find foreign module")
440 .foreign_items
441 .contains(&id)
442 })
443 },
444 native_libraries: native_libs::collect,
445 foreign_modules: foreign_modules::collect,
446 externally_implementable_items: eii::collect,
447
448 visible_parent_map: |tcx, ()| {
453 use std::collections::hash_map::Entry;
454 use std::collections::vec_deque::VecDeque;
455
456 let mut visible_parent_map: DefIdMap<DefId> = Default::default();
457 let mut fallback_map: Vec<(DefId, DefId)> = Default::default();
465
466 let bfs_queue = &mut VecDeque::new();
477
478 for &cnum in tcx.crates(()) {
479 if tcx.missing_extern_crate_item(cnum) {
481 continue;
482 }
483
484 bfs_queue.push_back(cnum.as_def_id());
485 }
486
487 let mut add_child = |bfs_queue: &mut VecDeque<_>, child: &ModChild, parent: DefId| {
488 if !child.vis.is_public() {
489 return;
490 }
491
492 if let Some(def_id) = child.res.opt_def_id() {
493 if child.ident.name == kw::Underscore {
494 fallback_map.push((def_id, parent));
495 return;
496 }
497
498 if tcx.is_doc_hidden(parent) {
499 fallback_map.push((def_id, parent));
500 return;
501 }
502
503 match visible_parent_map.entry(def_id) {
504 Entry::Occupied(mut entry) => {
505 if def_id.is_local() && entry.get().is_local() {
508 entry.insert(parent);
509 }
510 }
511 Entry::Vacant(entry) => {
512 entry.insert(parent);
513 if child.res.module_like_def_id().is_some() {
514 bfs_queue.push_back(def_id);
515 }
516 }
517 }
518 }
519 };
520
521 while let Some(def) = bfs_queue.pop_front() {
522 for child in tcx.module_children(def).iter() {
523 add_child(bfs_queue, child, def);
524 }
525 }
526
527 for (child, parent) in fallback_map {
532 visible_parent_map.entry(child).or_insert(parent);
533 }
534
535 visible_parent_map
536 },
537
538 dependency_formats: |tcx, ()| Arc::new(crate::dependency_format::calculate(tcx)),
539 has_global_allocator: |tcx, LocalCrate| CStore::from_tcx(tcx).has_global_allocator(),
540 has_alloc_error_handler: |tcx, LocalCrate| CStore::from_tcx(tcx).has_alloc_error_handler(),
541 postorder_cnums: |tcx, ()| {
542 tcx.arena.alloc_from_iter(
543 CStore::from_tcx(tcx).crate_dependencies_in_postorder(LOCAL_CRATE).into_iter(),
544 )
545 },
546 crates: |tcx, ()| {
547 tcx.untracked().cstore.freeze();
550 tcx.arena.alloc_from_iter(CStore::from_tcx(tcx).iter_crate_data().map(|(cnum, _)| cnum))
551 },
552 used_crates: |tcx, ()| {
553 tcx.untracked().cstore.freeze();
556 tcx.arena.alloc_from_iter(
557 CStore::from_tcx(tcx)
558 .iter_crate_data()
559 .filter_map(|(cnum, data)| data.used().then_some(cnum)),
560 )
561 },
562 ..providers.queries
563 };
564 provide_extern(&mut providers.extern_queries);
565}
566
567impl CStore {
568 pub fn ctor_untracked(&self, tcx: TyCtxt<'_>, def: DefId) -> Option<(CtorKind, DefId)> {
569 self.get_crate_data(def.krate).get_ctor(tcx, def.index)
570 }
571
572 pub fn load_macro_untracked(&self, tcx: TyCtxt<'_>, id: DefId) -> LoadedMacro {
573 let sess = tcx.sess;
574 let _prof_timer = sess.prof.generic_activity("metadata_load_macro");
575
576 let data = self.get_crate_data(id.krate);
577 if data.root.is_proc_macro_crate() {
578 LoadedMacro::ProcMacro(data.load_proc_macro(tcx, id.index))
579 } else {
580 LoadedMacro::MacroDef {
581 def: data.get_macro(tcx, id.index),
582 ident: data.item_ident(tcx, id.index),
583 attrs: data.get_item_attrs(tcx, id.index).collect(),
584 span: data.get_span(tcx, id.index),
585 edition: data.root.edition,
586 }
587 }
588 }
589
590 pub fn def_span_untracked(&self, tcx: TyCtxt<'_>, def_id: DefId) -> Span {
591 self.get_crate_data(def_id.krate).get_span(tcx, def_id.index)
592 }
593
594 pub fn def_kind_untracked(&self, tcx: TyCtxt<'_>, def: DefId) -> DefKind {
595 self.get_crate_data(def.krate).def_kind(tcx, def.index)
596 }
597
598 pub fn expn_that_defined_untracked(&self, tcx: TyCtxt<'_>, def_id: DefId) -> ExpnId {
599 self.get_crate_data(def_id.krate).get_expn_that_defined(tcx, def_id.index)
600 }
601
602 pub fn ambig_module_children_untracked(
603 &self,
604 tcx: TyCtxt<'_>,
605 def_id: DefId,
606 ) -> impl Iterator<Item = AmbigModChild> {
607 self.get_crate_data(def_id.krate).get_ambig_module_children(tcx, def_id.index)
608 }
609
610 pub fn num_def_ids_untracked(&self, cnum: CrateNum) -> usize {
614 self.get_crate_data(cnum).num_def_ids()
615 }
616
617 pub fn get_proc_macro_quoted_span_untracked(
618 &self,
619 tcx: TyCtxt<'_>,
620 cnum: CrateNum,
621 id: usize,
622 ) -> Span {
623 self.get_crate_data(cnum).get_proc_macro_quoted_span(tcx, id)
624 }
625
626 pub fn set_used_recursively(&mut self, tcx: TyCtxt<'_>, cnum: CrateNum) {
627 let cmeta = self.get_crate_data_mut(cnum);
628 if !cmeta.used {
629 cmeta.used = true;
630 let dependencies = mem::take(&mut cmeta.dependencies);
631 for &dep_cnum in &dependencies {
632 self.set_used_recursively(tcx, dep_cnum);
633 }
634 self.get_crate_data_mut(cnum).dependencies = dependencies;
635 }
636 }
637
638 pub(crate) fn update_extern_crate(
643 &mut self,
644 cnum: CrateNum,
645 name: Symbol,
646 extern_crate: ExternCrate,
647 ) {
648 debug_assert_eq!(
649 extern_crate.dependency_of, LOCAL_CRATE,
650 "this function should not be called on transitive dependencies"
651 );
652 self.set_resolved_extern_crate_name(name, cnum);
653 self.update_transitive_extern_crate_diagnostics(cnum, extern_crate);
654 }
655
656 fn update_transitive_extern_crate_diagnostics(
658 &mut self,
659 cnum: CrateNum,
660 extern_crate: ExternCrate,
661 ) {
662 let cmeta = self.get_crate_data_mut(cnum);
663 if cmeta.update_extern_crate_diagnostics(extern_crate) {
664 let extern_crate = ExternCrate { dependency_of: cnum, ..extern_crate };
666 let dependencies = mem::take(&mut cmeta.dependencies);
667 for &dep_cnum in &dependencies {
668 self.update_transitive_extern_crate_diagnostics(dep_cnum, extern_crate);
669 }
670 self.get_crate_data_mut(cnum).dependencies = dependencies;
671 }
672 }
673}
674
675impl CrateStore for CStore {
676 fn as_any(&self) -> &dyn Any {
677 self
678 }
679 fn untracked_as_any(&mut self) -> &mut dyn Any {
680 self
681 }
682
683 fn crate_name(&self, cnum: CrateNum) -> Symbol {
684 self.get_crate_data(cnum).root.header.name
685 }
686
687 fn stable_crate_id(&self, cnum: CrateNum) -> StableCrateId {
688 self.get_crate_data(cnum).root.stable_crate_id
689 }
690
691 fn def_key(&self, def: DefId) -> DefKey {
695 self.get_crate_data(def.krate).def_key(def.index)
696 }
697
698 fn def_path(&self, def: DefId) -> DefPath {
699 self.get_crate_data(def.krate).def_path(def.index)
700 }
701
702 fn def_path_hash(&self, def: DefId) -> DefPathHash {
703 self.get_crate_data(def.krate).def_path_hash(def.index)
704 }
705}
706
707fn provide_cstore_hooks(providers: &mut Providers) {
708 providers.hooks.def_path_hash_to_def_id_extern = |tcx, hash, stable_crate_id| {
709 let cstore = CStore::from_tcx(tcx);
712 let cnum = *tcx
713 .untracked()
714 .stable_crate_ids
715 .read()
716 .get(&stable_crate_id)
717 .unwrap_or_else(|| bug!("uninterned StableCrateId: {stable_crate_id:?}"));
718 assert_ne!(cnum, LOCAL_CRATE);
719 let def_index = cstore.get_crate_data(cnum).def_path_hash_to_def_index(hash)?;
720 Some(DefId { krate: cnum, index: def_index })
721 };
722
723 providers.hooks.expn_hash_to_expn_id = |tcx, cnum, index_guess, hash| {
724 let cstore = CStore::from_tcx(tcx);
725 cstore.get_crate_data(cnum).expn_hash_to_expn_id(tcx, index_guess, hash)
726 };
727 providers.hooks.import_source_files = |tcx, cnum| {
728 let cstore = CStore::from_tcx(tcx);
729 let cdata = cstore.get_crate_data(cnum);
730 for file_index in 0..cdata.root.source_map.size() {
731 cdata.imported_source_file(tcx, file_index as u32);
732 }
733 };
734}