1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
15 use rustc
::dep_graph
::DepTrackingMapConfig
;
16 use rustc
::middle
::cstore
::{CrateStore
, CrateSource
, LibSource
, DepKind
,
17 ExternCrate
, NativeLibrary
, MetadataLoader
, LinkMeta
,
18 LinkagePreference
, LoadedMacro
, EncodedMetadata
};
20 use rustc
::middle
::lang_items
;
21 use rustc
::session
::Session
;
22 use rustc
::ty
::{self, TyCtxt}
;
23 use rustc
::ty
::maps
::Providers
;
24 use rustc
::hir
::def_id
::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}
;
26 use rustc
::dep_graph
::{DepNode, GlobalMetaDataKind}
;
27 use rustc
::hir
::map
::{DefKey, DefPath, DisambiguatedDefPathData, DefPathHash}
;
28 use rustc
::hir
::map
::definitions
::DefPathTable
;
29 use rustc
::util
::nodemap
::{NodeSet, DefIdMap}
;
30 use rustc_back
::PanicStrategy
;
37 use syntax
::parse
::filemap_to_stream
;
38 use syntax
::symbol
::Symbol
;
39 use syntax_pos
::{Span, NO_EXPANSION}
;
40 use rustc
::hir
::svh
::Svh
;
43 macro_rules
! provide
{
44 (<$lt
:tt
> $tcx
:ident
, $def_id
:ident
, $cdata
:ident $
($name
:ident
=> $compute
:block
)*) => {
45 pub fn provide
<$lt
>(providers
: &mut Providers
<$lt
>) {
46 $
(fn $name
<'a
, $lt
:$lt
>($tcx
: TyCtxt
<'a
, $lt
, $lt
>, $def_id
: DefId
)
47 -> <ty
::queries
::$name
<$lt
> as
48 DepTrackingMapConfig
>::Value
{
49 assert
!(!$def_id
.is_local());
51 $tcx
.dep_graph
.read(DepNode
::MetaData($def_id
));
53 let $cdata
= $tcx
.sess
.cstore
.crate_data_as_rc_any($def_id
.krate
);
54 let $cdata
= $cdata
.downcast_ref
::<cstore
::CrateMetadata
>()
55 .expect("CrateStore crated ata is not a CrateMetadata");
59 *providers
= Providers
{
67 provide
! { <'tcx
> tcx
, def_id
, cdata
68 type_of
=> { cdata.get_type(def_id.index, tcx) }
69 generics_of
=> { tcx.alloc_generics(cdata.get_generics(def_id.index)) }
70 predicates_of
=> { cdata.get_predicates(def_id.index, tcx) }
71 super_predicates_of
=> { cdata.get_super_predicates(def_id.index, tcx) }
73 tcx
.alloc_trait_def(cdata
.get_trait_def(def_id
.index
))
75 adt_def
=> { cdata.get_adt_def(def_id.index, tcx) }
78 tcx
.calculate_dtor(def_id
, &mut |_
,_
| Ok(()))
80 variances_of
=> { Rc::new(cdata.get_item_variances(def_id.index)) }
81 associated_item_def_ids
=> {
82 let mut result
= vec
![];
83 cdata
.each_child_of_item(def_id
.index
, |child
| result
.push(child
.def
.def_id()));
86 associated_item
=> { cdata.get_associated_item(def_id.index) }
87 impl_trait_ref
=> { cdata.get_impl_trait(def_id.index, tcx) }
88 impl_polarity
=> { cdata.get_impl_polarity(def_id.index) }
89 coerce_unsized_info
=> {
90 cdata
.get_coerce_unsized_info(def_id
.index
).unwrap_or_else(|| {
91 bug
!("coerce_unsized_info: `{:?}` is missing its info", def_id
);
95 let mir
= cdata
.maybe_get_optimized_mir(tcx
, def_id
.index
).unwrap_or_else(|| {
96 bug
!("get_optimized_mir: missing MIR for `{:?}`", def_id
)
99 let mir
= tcx
.alloc_mir(mir
);
103 mir_const_qualif
=> { cdata.mir_const_qualif(def_id.index) }
104 typeck_tables_of
=> { cdata.item_body_tables(def_id.index, tcx) }
105 closure_kind
=> { cdata.closure_kind(def_id.index) }
106 closure_type
=> { cdata.closure_ty(def_id.index, tcx) }
107 inherent_impls
=> { Rc::new(cdata.get_inherent_implementations_for_type(def_id.index)) }
108 is_foreign_item
=> { cdata.is_foreign_item(def_id.index) }
109 is_default_impl
=> { cdata.is_default_impl(def_id.index) }
110 describe_def
=> { cdata.get_def(def_id.index) }
111 def_span
=> { cdata.get_span(def_id.index, &tcx.sess) }
112 stability
=> { cdata.get_stability(def_id.index) }
113 deprecation
=> { cdata.get_deprecation(def_id.index) }
114 item_attrs
=> { cdata.get_item_attrs(def_id.index, &tcx.dep_graph) }
115 // FIXME(#38501) We've skipped a `read` on the `HirBody` of
116 // a `fn` when encoding, so the dep-tracking wouldn't work.
117 // This is only used by rustdoc anyway, which shouldn't have
118 // incremental recompilation ever enabled.
119 fn_arg_names
=> { cdata.get_fn_arg_names(def_id.index) }
120 impl_parent
=> { cdata.get_parent_impl(def_id.index) }
121 trait_of_item
=> { cdata.get_trait_of_item(def_id.index) }
122 is_exported_symbol
=> {
123 let dep_node
= cdata
.metadata_dep_node(GlobalMetaDataKind
::ExportedSymbols
);
124 cdata
.exported_symbols
.get(&tcx
.dep_graph
, dep_node
).contains(&def_id
.index
)
126 item_body_nested_bodies
=> { Rc::new(cdata.item_body_nested_bodies(def_id.index)) }
127 const_is_rvalue_promotable_to_static
=> {
128 cdata
.const_is_rvalue_promotable_to_static(def_id
.index
)
130 is_mir_available
=> { cdata.is_item_mir_available(def_id.index) }
133 impl CrateStore
for cstore
::CStore
{
134 fn crate_data_as_rc_any(&self, krate
: CrateNum
) -> Rc
<Any
> {
135 self.get_crate_data(krate
)
138 fn metadata_loader(&self) -> &MetadataLoader
{
139 &*self.metadata_loader
142 fn visibility(&self, def
: DefId
) -> ty
::Visibility
{
143 self.dep_graph
.read(DepNode
::MetaData(def
));
144 self.get_crate_data(def
.krate
).get_visibility(def
.index
)
147 fn item_generics_cloned(&self, def
: DefId
) -> ty
::Generics
{
148 self.dep_graph
.read(DepNode
::MetaData(def
));
149 self.get_crate_data(def
.krate
).get_generics(def
.index
)
152 fn implementations_of_trait(&self, filter
: Option
<DefId
>) -> Vec
<DefId
>
154 let mut result
= vec
![];
156 self.iter_crate_data(|_
, cdata
| {
157 cdata
.get_implementations_for_trait(filter
, &self.dep_graph
, &mut result
)
162 fn impl_defaultness(&self, def
: DefId
) -> hir
::Defaultness
164 self.dep_graph
.read(DepNode
::MetaData(def
));
165 self.get_crate_data(def
.krate
).get_impl_defaultness(def
.index
)
168 fn associated_item_cloned(&self, def
: DefId
) -> ty
::AssociatedItem
170 self.dep_graph
.read(DepNode
::MetaData(def
));
171 self.get_crate_data(def
.krate
).get_associated_item(def
.index
)
174 fn is_const_fn(&self, did
: DefId
) -> bool
176 self.dep_graph
.read(DepNode
::MetaData(did
));
177 self.get_crate_data(did
.krate
).is_const_fn(did
.index
)
180 fn is_statically_included_foreign_item(&self, def_id
: DefId
) -> bool
182 self.do_is_statically_included_foreign_item(def_id
)
185 fn is_dllimport_foreign_item(&self, def_id
: DefId
) -> bool
{
186 if def_id
.krate
== LOCAL_CRATE
{
187 self.dllimport_foreign_items
.borrow().contains(&def_id
.index
)
189 self.get_crate_data(def_id
.krate
)
190 .is_dllimport_foreign_item(def_id
.index
, &self.dep_graph
)
194 fn dylib_dependency_formats(&self, cnum
: CrateNum
)
195 -> Vec
<(CrateNum
, LinkagePreference
)>
197 self.get_crate_data(cnum
).get_dylib_dependency_formats(&self.dep_graph
)
200 fn dep_kind(&self, cnum
: CrateNum
) -> DepKind
202 let data
= self.get_crate_data(cnum
);
203 let dep_node
= data
.metadata_dep_node(GlobalMetaDataKind
::CrateDeps
);
204 self.dep_graph
.read(dep_node
);
208 fn export_macros(&self, cnum
: CrateNum
) {
209 let data
= self.get_crate_data(cnum
);
210 let dep_node
= data
.metadata_dep_node(GlobalMetaDataKind
::CrateDeps
);
212 self.dep_graph
.read(dep_node
);
213 if data
.dep_kind
.get() == DepKind
::UnexportedMacrosOnly
{
214 data
.dep_kind
.set(DepKind
::MacrosOnly
)
218 fn lang_items(&self, cnum
: CrateNum
) -> Vec
<(DefIndex
, usize)>
220 self.get_crate_data(cnum
).get_lang_items(&self.dep_graph
)
223 fn missing_lang_items(&self, cnum
: CrateNum
)
224 -> Vec
<lang_items
::LangItem
>
226 self.get_crate_data(cnum
).get_missing_lang_items(&self.dep_graph
)
229 fn is_allocator(&self, cnum
: CrateNum
) -> bool
231 self.get_crate_data(cnum
).is_allocator(&self.dep_graph
)
234 fn is_panic_runtime(&self, cnum
: CrateNum
) -> bool
236 self.get_crate_data(cnum
).is_panic_runtime(&self.dep_graph
)
239 fn is_compiler_builtins(&self, cnum
: CrateNum
) -> bool
{
240 self.get_crate_data(cnum
).is_compiler_builtins(&self.dep_graph
)
243 fn is_sanitizer_runtime(&self, cnum
: CrateNum
) -> bool
{
244 self.get_crate_data(cnum
).is_sanitizer_runtime(&self.dep_graph
)
247 fn panic_strategy(&self, cnum
: CrateNum
) -> PanicStrategy
{
248 self.get_crate_data(cnum
).panic_strategy(&self.dep_graph
)
251 fn crate_name(&self, cnum
: CrateNum
) -> Symbol
253 self.get_crate_data(cnum
).name
256 fn original_crate_name(&self, cnum
: CrateNum
) -> Symbol
258 self.get_crate_data(cnum
).name()
261 fn extern_crate(&self, cnum
: CrateNum
) -> Option
<ExternCrate
>
263 self.get_crate_data(cnum
).extern_crate
.get()
266 fn crate_hash(&self, cnum
: CrateNum
) -> Svh
268 self.get_crate_hash(cnum
)
271 fn crate_disambiguator(&self, cnum
: CrateNum
) -> Symbol
273 self.get_crate_data(cnum
).disambiguator()
276 fn plugin_registrar_fn(&self, cnum
: CrateNum
) -> Option
<DefId
>
278 self.get_crate_data(cnum
).root
.plugin_registrar_fn
.map(|index
| DefId
{
284 fn derive_registrar_fn(&self, cnum
: CrateNum
) -> Option
<DefId
>
286 self.get_crate_data(cnum
).root
.macro_derive_registrar
.map(|index
| DefId
{
292 fn native_libraries(&self, cnum
: CrateNum
) -> Vec
<NativeLibrary
>
294 self.get_crate_data(cnum
).get_native_libraries(&self.dep_graph
)
297 fn exported_symbols(&self, cnum
: CrateNum
) -> Vec
<DefId
>
299 self.get_crate_data(cnum
).get_exported_symbols(&self.dep_graph
)
302 fn is_no_builtins(&self, cnum
: CrateNum
) -> bool
{
303 self.get_crate_data(cnum
).is_no_builtins(&self.dep_graph
)
306 fn retrace_path(&self,
308 path
: &[DisambiguatedDefPathData
])
310 let cdata
= self.get_crate_data(cnum
);
313 .map(|index
| DefId { krate: cnum, index: index }
)
316 /// Returns the `DefKey` for a given `DefId`. This indicates the
317 /// parent `DefId` as well as some idea of what kind of data the
318 /// `DefId` refers to.
319 fn def_key(&self, def
: DefId
) -> DefKey
{
320 // Note: loading the def-key (or def-path) for a def-id is not
321 // a *read* of its metadata. This is because the def-id is
322 // really just an interned shorthand for a def-path, which is the
323 // canonical name for an item.
325 // self.dep_graph.read(DepNode::MetaData(def));
326 self.get_crate_data(def
.krate
).def_key(def
.index
)
329 fn def_path(&self, def
: DefId
) -> DefPath
{
330 // See `Note` above in `def_key()` for why this read is
333 // self.dep_graph.read(DepNode::MetaData(def));
334 self.get_crate_data(def
.krate
).def_path(def
.index
)
337 fn def_path_hash(&self, def
: DefId
) -> DefPathHash
{
338 self.get_crate_data(def
.krate
).def_path_hash(def
.index
)
341 fn def_path_table(&self, cnum
: CrateNum
) -> Rc
<DefPathTable
> {
342 self.get_crate_data(cnum
).def_path_table
.clone()
345 fn struct_field_names(&self, def
: DefId
) -> Vec
<ast
::Name
>
347 self.dep_graph
.read(DepNode
::MetaData(def
));
348 self.get_crate_data(def
.krate
).get_struct_field_names(def
.index
)
351 fn item_children(&self, def_id
: DefId
) -> Vec
<def
::Export
>
353 self.dep_graph
.read(DepNode
::MetaData(def_id
));
354 let mut result
= vec
![];
355 self.get_crate_data(def_id
.krate
)
356 .each_child_of_item(def_id
.index
, |child
| result
.push(child
));
360 fn load_macro(&self, id
: DefId
, sess
: &Session
) -> LoadedMacro
{
361 let data
= self.get_crate_data(id
.krate
);
362 if let Some(ref proc_macros
) = data
.proc_macros
{
363 return LoadedMacro
::ProcMacro(proc_macros
[id
.index
.as_usize() - 1].1.clone());
366 let (name
, def
) = data
.get_macro(id
.index
);
367 let source_name
= format
!("<{} macros>", name
);
369 let filemap
= sess
.parse_sess
.codemap().new_filemap(source_name
, def
.body
);
370 let local_span
= Span { lo: filemap.start_pos, hi: filemap.end_pos, ctxt: NO_EXPANSION }
;
371 let body
= filemap_to_stream(&sess
.parse_sess
, filemap
);
373 // Mark the attrs as used
374 let attrs
= data
.get_item_attrs(id
.index
, &self.dep_graph
);
375 for attr
in attrs
.iter() {
376 attr
::mark_used(attr
);
379 let name
= data
.def_key(id
.index
).disambiguated_data
.data
380 .get_opt_name().expect("no name in load_macro");
381 sess
.imported_macro_spans
.borrow_mut()
382 .insert(local_span
, (name
.to_string(), data
.get_span(id
.index
, sess
)));
384 LoadedMacro
::MacroDef(ast
::Item
{
385 ident
: ast
::Ident
::with_empty_ctxt(name
),
386 id
: ast
::DUMMY_NODE_ID
,
388 attrs
: attrs
.iter().cloned().collect(),
389 node
: ast
::ItemKind
::MacroDef(ast
::MacroDef
{
393 vis
: ast
::Visibility
::Inherited
,
397 fn item_body
<'a
, 'tcx
>(&self,
398 tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>,
401 if let Some(cached
) = tcx
.hir
.get_inlined_body(def_id
) {
405 self.dep_graph
.read(DepNode
::MetaData(def_id
));
406 debug
!("item_body({:?}): inlining item", def_id
);
408 self.get_crate_data(def_id
.krate
).item_body(tcx
, def_id
.index
)
411 fn crates(&self) -> Vec
<CrateNum
>
413 let mut result
= vec
![];
414 self.iter_crate_data(|cnum
, _
| result
.push(cnum
));
418 fn used_libraries(&self) -> Vec
<NativeLibrary
>
420 self.get_used_libraries().borrow().clone()
423 fn used_link_args(&self) -> Vec
<String
>
425 self.get_used_link_args().borrow().clone()
427 fn used_crates(&self, prefer
: LinkagePreference
) -> Vec
<(CrateNum
, LibSource
)>
429 self.do_get_used_crates(prefer
)
432 fn used_crate_source(&self, cnum
: CrateNum
) -> CrateSource
434 self.get_crate_data(cnum
).source
.clone()
437 fn extern_mod_stmt_cnum(&self, emod_id
: ast
::NodeId
) -> Option
<CrateNum
>
439 self.do_extern_mod_stmt_cnum(emod_id
)
442 fn encode_metadata
<'a
, 'tcx
>(&self,
443 tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>,
444 link_meta
: &LinkMeta
,
448 encoder
::encode_metadata(tcx
, link_meta
, reachable
)
451 fn metadata_encoding_version(&self) -> &[u8]
453 schema
::METADATA_HEADER
456 /// Returns a map from a sufficiently visible external item (i.e. an external item that is
457 /// visible from at least one local module) to a sufficiently visible parent (considering
458 /// modules that re-export the external item to be parents).
459 fn visible_parent_map
<'a
>(&'a
self) -> ::std
::cell
::Ref
<'a
, DefIdMap
<DefId
>> {
461 let visible_parent_map
= self.visible_parent_map
.borrow();
462 if !visible_parent_map
.is_empty() {
463 return visible_parent_map
;
467 use std
::collections
::vec_deque
::VecDeque
;
468 use std
::collections
::hash_map
::Entry
;
470 let mut visible_parent_map
= self.visible_parent_map
.borrow_mut();
472 for cnum
in (1 .. self.next_crate_num().as_usize()).map(CrateNum
::new
) {
473 let cdata
= self.get_crate_data(cnum
);
475 match cdata
.extern_crate
.get() {
476 // Ignore crates without a corresponding local `extern crate` item.
477 Some(extern_crate
) if !extern_crate
.direct
=> continue,
481 let mut bfs_queue
= &mut VecDeque
::new();
482 let mut add_child
= |bfs_queue
: &mut VecDeque
<_
>, child
: def
::Export
, parent
: DefId
| {
483 let child
= child
.def
.def_id();
485 if self.visibility(child
) != ty
::Visibility
::Public
{
489 match visible_parent_map
.entry(child
) {
490 Entry
::Occupied(mut entry
) => {
491 // If `child` is defined in crate `cnum`, ensure
492 // that it is mapped to a parent in `cnum`.
493 if child
.krate
== cnum
&& entry
.get().krate
!= cnum
{
494 entry
.insert(parent
);
497 Entry
::Vacant(entry
) => {
498 entry
.insert(parent
);
499 bfs_queue
.push_back(child
);
504 bfs_queue
.push_back(DefId
{
506 index
: CRATE_DEF_INDEX
508 while let Some(def
) = bfs_queue
.pop_front() {
509 for child
in self.item_children(def
) {
510 add_child(bfs_queue
, child
, def
);
515 drop(visible_parent_map
);
516 self.visible_parent_map
.borrow()