1 use crate::creader
::{CStore, LoadedMacro}
;
2 use crate::foreign_modules
;
3 use crate::native_libs
;
4 use crate::rmeta
::{self, encoder}
;
7 use rustc_ast
::expand
::allocator
::AllocatorKind
;
8 use rustc_data_structures
::stable_map
::FxHashMap
;
9 use rustc_data_structures
::svh
::Svh
;
11 use rustc_hir
::def
::DefKind
;
12 use rustc_hir
::def_id
::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE}
;
13 use rustc_hir
::definitions
::{DefKey, DefPath, DefPathHash}
;
14 use rustc_middle
::hir
::exports
::Export
;
15 use rustc_middle
::middle
::cstore
::ForeignModule
;
16 use rustc_middle
::middle
::cstore
::{CrateSource, CrateStore, EncodedMetadata}
;
17 use rustc_middle
::middle
::exported_symbols
::ExportedSymbol
;
18 use rustc_middle
::middle
::stability
::DeprecationEntry
;
19 use rustc_middle
::ty
::query
::Providers
;
20 use rustc_middle
::ty
::{self, TyCtxt}
;
21 use rustc_session
::utils
::NativeLibKind
;
22 use rustc_session
::{CrateDisambiguator, Session}
;
23 use rustc_span
::source_map
::{Span, Spanned}
;
24 use rustc_span
::symbol
::Symbol
;
26 use rustc_data_structures
::sync
::Lrc
;
27 use rustc_span
::ExpnId
;
28 use smallvec
::SmallVec
;
31 macro_rules
! provide
{
32 (<$lt
:tt
> $tcx
:ident
, $def_id
:ident
, $other
:ident
, $cdata
:ident
,
33 $
($name
:ident
=> $compute
:block
)*) => {
34 pub fn provide_extern(providers
: &mut Providers
) {
37 def_id_arg
: ty
::query
::query_keys
::$name
<$lt
>,
38 ) -> ty
::query
::query_values
::$name
<$lt
> {
40 $tcx
.prof
.generic_activity(concat
!("metadata_decode_entry_", stringify
!($name
)));
42 #[allow(unused_variables)]
43 let ($def_id
, $other
) = def_id_arg
.into_args();
44 assert
!(!$def_id
.is_local());
46 // External query providers call `crate_hash` in order to register a dependency
47 // on the crate metadata. The exception is `crate_hash` itself, which obviously
48 // doesn't need to do this (and can't, as it would cause a query cycle).
49 use rustc_middle
::dep_graph
::DepKind
;
50 if DepKind
::$name
!= DepKind
::crate_hash
&& $tcx
.dep_graph
.is_fully_enabled() {
51 $tcx
.ensure().crate_hash($def_id
.krate
);
54 let $cdata
= CStore
::from_tcx($tcx
).get_crate_data($def_id
.krate
);
59 *providers
= Providers
{
67 // small trait to work around different signature queries all being defined via
70 fn into_args(self) -> (DefId
, DefId
);
73 impl IntoArgs
for DefId
{
74 fn into_args(self) -> (DefId
, DefId
) {
79 impl IntoArgs
for CrateNum
{
80 fn into_args(self) -> (DefId
, DefId
) {
81 (self.as_def_id(), self.as_def_id())
85 impl IntoArgs
for (CrateNum
, DefId
) {
86 fn into_args(self) -> (DefId
, DefId
) {
87 (self.0.as_def_id(), self.1)
91 provide
! { <'tcx
> tcx
, def_id
, other
, cdata
,
92 type_of
=> { cdata.get_type(def_id.index, tcx) }
93 generics_of
=> { cdata.get_generics(def_id.index, tcx.sess) }
94 explicit_predicates_of
=> { cdata.get_explicit_predicates(def_id.index, tcx) }
95 inferred_outlives_of
=> { cdata.get_inferred_outlives(def_id.index, tcx) }
96 super_predicates_of
=> { cdata.get_super_predicates(def_id.index, tcx) }
97 explicit_item_bounds
=> { cdata.get_explicit_item_bounds(def_id.index, tcx) }
98 trait_def
=> { cdata.get_trait_def(def_id.index, tcx.sess) }
99 adt_def
=> { cdata.get_adt_def(def_id.index, tcx) }
102 tcx
.calculate_dtor(def_id
, |_
,_
| Ok(()))
104 variances_of
=> { tcx.arena.alloc_from_iter(cdata.get_item_variances(def_id.index)) }
105 associated_item_def_ids
=> {
106 let mut result
= SmallVec
::<[_
; 8]>::new();
107 cdata
.each_child_of_item(def_id
.index
,
108 |child
| result
.push(child
.res
.def_id()), tcx
.sess
);
109 tcx
.arena
.alloc_slice(&result
)
111 associated_item
=> { cdata.get_associated_item(def_id.index, tcx.sess) }
112 impl_trait_ref
=> { cdata.get_impl_trait(def_id.index, tcx) }
113 impl_polarity
=> { cdata.get_impl_polarity(def_id.index) }
114 coerce_unsized_info
=> {
115 cdata
.get_coerce_unsized_info(def_id
.index
).unwrap_or_else(|| {
116 bug
!("coerce_unsized_info: `{:?}` is missing its info", def_id
);
119 optimized_mir
=> { tcx.arena.alloc(cdata.get_optimized_mir(tcx, def_id.index)) }
120 mir_for_ctfe
=> { tcx.arena.alloc(cdata.get_mir_for_ctfe(tcx, def_id.index)) }
121 promoted_mir
=> { tcx.arena.alloc(cdata.get_promoted_mir(tcx, def_id.index)) }
122 mir_abstract_const
=> { cdata.get_mir_abstract_const(tcx, def_id.index) }
123 unused_generic_params
=> { cdata.get_unused_generic_params(def_id.index) }
124 const_param_default
=> { tcx.mk_const(cdata.get_const_param_default(tcx, def_id.index)) }
125 mir_const_qualif
=> { cdata.mir_const_qualif(def_id.index) }
126 fn_sig
=> { cdata.fn_sig(def_id.index, tcx) }
127 inherent_impls
=> { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }
128 is_const_fn_raw
=> { cdata.is_const_fn_raw(def_id.index) }
129 asyncness
=> { cdata.asyncness(def_id.index) }
130 is_foreign_item
=> { cdata.is_foreign_item(def_id.index) }
131 static_mutability
=> { cdata.static_mutability(def_id.index) }
132 generator_kind
=> { cdata.generator_kind(def_id.index) }
133 opt_def_kind
=> { Some(cdata.def_kind(def_id.index)) }
134 def_span
=> { cdata.get_span(def_id.index, &tcx.sess) }
136 cdata
.try_item_ident(def_id
.index
, &tcx
.sess
).ok().map(|ident
| ident
.span
)
138 lookup_stability
=> {
139 cdata
.get_stability(def_id
.index
).map(|s
| tcx
.intern_stability(s
))
141 lookup_const_stability
=> {
142 cdata
.get_const_stability(def_id
.index
).map(|s
| tcx
.intern_const_stability(s
))
144 lookup_deprecation_entry
=> {
145 cdata
.get_deprecation(def_id
.index
).map(DeprecationEntry
::external
)
147 item_attrs
=> { tcx
.arena
.alloc_from_iter(
148 cdata
.get_item_attrs(def_id
.index
, tcx
.sess
)
150 fn_arg_names
=> { cdata.get_fn_param_names(tcx, def_id.index) }
151 rendered_const
=> { cdata.get_rendered_const(def_id.index) }
152 impl_parent
=> { cdata.get_parent_impl(def_id.index) }
153 trait_of_item
=> { cdata.get_trait_of_item(def_id.index) }
154 is_mir_available
=> { cdata.is_item_mir_available(def_id.index) }
155 is_ctfe_mir_available
=> { cdata.is_ctfe_mir_available(def_id.index) }
157 dylib_dependency_formats
=> { cdata.get_dylib_dependency_formats(tcx) }
158 is_panic_runtime
=> { cdata.root.panic_runtime }
159 is_compiler_builtins
=> { cdata.root.compiler_builtins }
160 has_global_allocator
=> { cdata.root.has_global_allocator }
161 has_panic_handler
=> { cdata.root.has_panic_handler }
162 is_profiler_runtime
=> { cdata.root.profiler_runtime }
163 panic_strategy
=> { cdata.root.panic_strategy }
165 let r
= *cdata
.extern_crate
.lock();
166 r
.map(|c
| &*tcx
.arena
.alloc(c
))
168 is_no_builtins
=> { cdata.root.no_builtins }
169 symbol_mangling_version
=> { cdata.root.symbol_mangling_version }
170 impl_defaultness
=> { cdata.get_impl_defaultness(def_id.index) }
171 reachable_non_generics
=> {
172 let reachable_non_generics
= tcx
173 .exported_symbols(cdata
.cnum
)
175 .filter_map(|&(exported_symbol
, export_level
)| {
176 if let ExportedSymbol
::NonGeneric(def_id
) = exported_symbol
{
177 Some((def_id
, export_level
))
184 reachable_non_generics
186 native_libraries
=> { Lrc::new(cdata.get_native_libraries(tcx.sess)) }
187 foreign_modules
=> { cdata.get_foreign_modules(tcx) }
188 plugin_registrar_fn
=> {
189 cdata
.root
.plugin_registrar_fn
.map(|index
| {
190 DefId { krate: def_id.krate, index }
193 proc_macro_decls_static
=> {
194 cdata
.root
.proc_macro_data
.as_ref().map(|data
| {
197 index
: data
.proc_macro_decls_static
,
201 crate_disambiguator
=> { cdata.root.disambiguator }
202 crate_hash
=> { cdata.root.hash }
203 crate_host_hash
=> { cdata.host_hash }
204 original_crate_name
=> { cdata.root.name }
206 extra_filename
=> { cdata.root.extra_filename.clone() }
208 implementations_of_trait
=> {
209 cdata
.get_implementations_for_trait(tcx
, Some(other
))
212 all_trait_implementations
=> {
213 cdata
.get_implementations_for_trait(tcx
, None
)
216 visibility
=> { cdata.get_visibility(def_id.index) }
218 let r
= *cdata
.dep_kind
.lock();
221 crate_name
=> { cdata.root.name }
223 let mut result
= SmallVec
::<[_
; 8]>::new();
224 cdata
.each_child_of_item(def_id
.index
, |child
| result
.push(child
), tcx
.sess
);
225 tcx
.arena
.alloc_slice(&result
)
227 defined_lib_features
=> { cdata.get_lib_features(tcx) }
228 defined_lang_items
=> { cdata.get_lang_items(tcx) }
229 diagnostic_items
=> { cdata.get_diagnostic_items() }
230 missing_lang_items
=> { cdata.get_missing_lang_items(tcx) }
232 missing_extern_crate_item
=> {
233 let r
= matches
!(*cdata
.extern_crate
.borrow(), Some(extern_crate
) if !extern_crate
.is_direct());
237 used_crate_source
=> { Lrc::new(cdata.source.clone()) }
239 exported_symbols
=> {
240 let syms
= cdata
.exported_symbols(tcx
);
242 // FIXME rust-lang/rust#64319, rust-lang/rust#64872: We want
243 // to block export of generics from dylibs, but we must fix
244 // rust-lang/rust#65890 before we can do that robustly.
249 crate_extern_paths
=> { cdata.source().paths().cloned().collect() }
250 expn_that_defined
=> { cdata.get_expn_that_defined(def_id.index, tcx.sess) }
253 pub fn provide(providers
: &mut Providers
) {
254 // FIXME(#44234) - almost all of these queries have no sub-queries and
255 // therefore no actual inputs, they're just reading tables calculated in
256 // resolve! Does this work? Unsure! That's what the issue is about
257 *providers
= Providers
{
258 is_dllimport_foreign_item
: |tcx
, id
| match tcx
.native_library_kind(id
) {
259 Some(NativeLibKind
::Dylib
| NativeLibKind
::RawDylib
| NativeLibKind
::Unspecified
) => {
264 is_statically_included_foreign_item
: |tcx
, id
| {
266 tcx
.native_library_kind(id
),
267 Some(NativeLibKind
::StaticBundle
| NativeLibKind
::StaticNoBundle
)
270 native_library_kind
: |tcx
, id
| {
271 tcx
.native_libraries(id
.krate
)
273 .filter(|lib
| native_libs
::relevant_lib(&tcx
.sess
, lib
))
275 let fm_id
= match lib
.foreign_module
{
277 None
=> return false,
279 let map
= tcx
.foreign_modules(id
.krate
);
281 .expect("failed to find foreign module")
287 native_libraries
: |tcx
, cnum
| {
288 assert_eq
!(cnum
, LOCAL_CRATE
);
289 Lrc
::new(native_libs
::collect(tcx
))
291 foreign_modules
: |tcx
, cnum
| {
292 assert_eq
!(cnum
, LOCAL_CRATE
);
293 let modules
: FxHashMap
<DefId
, ForeignModule
> =
294 foreign_modules
::collect(tcx
).into_iter().map(|m
| (m
.def_id
, m
)).collect();
298 // Returns a map from a sufficiently visible external item (i.e., an
299 // external item that is visible from at least one local module) to a
300 // sufficiently visible parent (considering modules that re-export the
301 // external item to be parents).
302 visible_parent_map
: |tcx
, cnum
| {
303 use std
::collections
::hash_map
::Entry
;
304 use std
::collections
::vec_deque
::VecDeque
;
306 assert_eq
!(cnum
, LOCAL_CRATE
);
307 let mut visible_parent_map
: DefIdMap
<DefId
> = Default
::default();
309 // Issue 46112: We want the map to prefer the shortest
310 // paths when reporting the path to an item. Therefore we
311 // build up the map via a breadth-first search (BFS),
312 // which naturally yields minimal-length paths.
314 // Note that it needs to be a BFS over the whole forest of
315 // crates, not just each individual crate; otherwise you
316 // only get paths that are locally minimal with respect to
317 // whatever crate we happened to encounter first in this
318 // traversal, but not globally minimal across all crates.
319 let bfs_queue
= &mut VecDeque
::new();
321 // Preferring shortest paths alone does not guarantee a
322 // deterministic result; so sort by crate num to avoid
323 // hashtable iteration non-determinism. This only makes
324 // things as deterministic as crate-nums assignment is,
325 // which is to say, its not deterministic in general. But
326 // we believe that libstd is consistently assigned crate
327 // num 1, so it should be enough to resolve #46112.
328 let mut crates
: Vec
<CrateNum
> = (*tcx
.crates()).to_owned();
331 for &cnum
in crates
.iter() {
332 // Ignore crates without a corresponding local `extern crate` item.
333 if tcx
.missing_extern_crate_item(cnum
) {
337 bfs_queue
.push_back(DefId { krate: cnum, index: CRATE_DEF_INDEX }
);
340 // (restrict scope of mutable-borrow of `visible_parent_map`)
342 let visible_parent_map
= &mut visible_parent_map
;
344 |bfs_queue
: &mut VecDeque
<_
>, child
: &Export
<hir
::HirId
>, parent
: DefId
| {
345 if child
.vis
!= ty
::Visibility
::Public
{
349 if let Some(child
) = child
.res
.opt_def_id() {
350 match visible_parent_map
.entry(child
) {
351 Entry
::Occupied(mut entry
) => {
352 // If `child` is defined in crate `cnum`, ensure
353 // that it is mapped to a parent in `cnum`.
354 if child
.krate
== cnum
&& entry
.get().krate
!= cnum
{
355 entry
.insert(parent
);
358 Entry
::Vacant(entry
) => {
359 entry
.insert(parent
);
360 bfs_queue
.push_back(child
);
366 while let Some(def
) = bfs_queue
.pop_front() {
367 for child
in tcx
.item_children(def
).iter() {
368 add_child(bfs_queue
, child
, def
);
376 dependency_formats
: |tcx
, cnum
| {
377 assert_eq
!(cnum
, LOCAL_CRATE
);
378 Lrc
::new(crate::dependency_format
::calculate(tcx
))
380 has_global_allocator
: |tcx
, cnum
| {
381 assert_eq
!(cnum
, LOCAL_CRATE
);
382 CStore
::from_tcx(tcx
).has_global_allocator()
384 postorder_cnums
: |tcx
, cnum
| {
385 assert_eq
!(cnum
, LOCAL_CRATE
);
386 tcx
.arena
.alloc_slice(&CStore
::from_tcx(tcx
).crate_dependencies_in_postorder(cnum
))
394 pub fn struct_field_names_untracked(&self, def
: DefId
, sess
: &Session
) -> Vec
<Spanned
<Symbol
>> {
395 self.get_crate_data(def
.krate
).get_struct_field_names(def
.index
, sess
)
398 pub fn item_children_untracked(
402 ) -> Vec
<Export
<hir
::HirId
>> {
403 let mut result
= vec
![];
404 self.get_crate_data(def_id
.krate
).each_child_of_item(
406 |child
| result
.push(child
),
412 pub fn load_macro_untracked(&self, id
: DefId
, sess
: &Session
) -> LoadedMacro
{
413 let _prof_timer
= sess
.prof
.generic_activity("metadata_load_macro");
415 let data
= self.get_crate_data(id
.krate
);
416 if data
.root
.is_proc_macro_crate() {
417 return LoadedMacro
::ProcMacro(data
.load_proc_macro(id
.index
, sess
));
420 let span
= data
.get_span(id
.index
, sess
);
422 let attrs
= data
.get_item_attrs(id
.index
, sess
).collect();
424 let ident
= data
.item_ident(id
.index
, sess
);
426 LoadedMacro
::MacroDef(
429 id
: ast
::DUMMY_NODE_ID
,
432 kind
: ast
::ItemKind
::MacroDef(data
.get_macro(id
.index
, sess
)),
433 vis
: ast
::Visibility
{
434 span
: span
.shrink_to_lo(),
435 kind
: ast
::VisibilityKind
::Inherited
,
444 pub fn associated_item_cloned_untracked(&self, def
: DefId
, sess
: &Session
) -> ty
::AssocItem
{
445 self.get_crate_data(def
.krate
).get_associated_item(def
.index
, sess
)
448 pub fn crate_source_untracked(&self, cnum
: CrateNum
) -> CrateSource
{
449 self.get_crate_data(cnum
).source
.clone()
452 pub fn get_span_untracked(&self, def_id
: DefId
, sess
: &Session
) -> Span
{
453 self.get_crate_data(def_id
.krate
).get_span(def_id
.index
, sess
)
456 pub fn item_generics_num_lifetimes(&self, def_id
: DefId
, sess
: &Session
) -> usize {
457 self.get_crate_data(def_id
.krate
).get_generics(def_id
.index
, sess
).own_counts().lifetimes
460 pub fn module_expansion_untracked(&self, def_id
: DefId
, sess
: &Session
) -> ExpnId
{
461 self.get_crate_data(def_id
.krate
).module_expansion(def_id
.index
, sess
)
464 pub fn num_def_ids(&self, cnum
: CrateNum
) -> usize {
465 self.get_crate_data(cnum
).num_def_ids()
468 pub fn item_attrs(&self, def_id
: DefId
, sess
: &Session
) -> Vec
<ast
::Attribute
> {
469 self.get_crate_data(def_id
.krate
).get_item_attrs(def_id
.index
, sess
).collect()
473 impl CrateStore
for CStore
{
474 fn as_any(&self) -> &dyn Any
{
478 fn crate_name_untracked(&self, cnum
: CrateNum
) -> Symbol
{
479 self.get_crate_data(cnum
).root
.name
482 fn crate_is_private_dep_untracked(&self, cnum
: CrateNum
) -> bool
{
483 self.get_crate_data(cnum
).private_dep
486 fn crate_disambiguator_untracked(&self, cnum
: CrateNum
) -> CrateDisambiguator
{
487 self.get_crate_data(cnum
).root
.disambiguator
490 fn crate_hash_untracked(&self, cnum
: CrateNum
) -> Svh
{
491 self.get_crate_data(cnum
).root
.hash
494 /// Returns the `DefKey` for a given `DefId`. This indicates the
495 /// parent `DefId` as well as some idea of what kind of data the
496 /// `DefId` refers to.
497 fn def_key(&self, def
: DefId
) -> DefKey
{
498 self.get_crate_data(def
.krate
).def_key(def
.index
)
501 fn def_kind(&self, def
: DefId
) -> DefKind
{
502 self.get_crate_data(def
.krate
).def_kind(def
.index
)
505 fn def_path(&self, def
: DefId
) -> DefPath
{
506 self.get_crate_data(def
.krate
).def_path(def
.index
)
509 fn def_path_hash(&self, def
: DefId
) -> DefPathHash
{
510 self.get_crate_data(def
.krate
).def_path_hash(def
.index
)
513 // See `CrateMetadataRef::def_path_hash_to_def_id` for more details
514 fn def_path_hash_to_def_id(
520 self.get_crate_data(cnum
).def_path_hash_to_def_id(cnum
, index_guess
, hash
)
523 fn crates_untracked(&self) -> Vec
<CrateNum
> {
524 let mut result
= vec
![];
525 self.iter_crate_data(|cnum
, _
| result
.push(cnum
));
529 fn encode_metadata(&self, tcx
: TyCtxt
<'_
>) -> EncodedMetadata
{
530 encoder
::encode_metadata(tcx
)
533 fn metadata_encoding_version(&self) -> &[u8] {
534 rmeta
::METADATA_HEADER
537 fn allocator_kind(&self) -> Option
<AllocatorKind
> {
538 self.allocator_kind()