]> git.proxmox.com Git - rustc.git/blob - src/librustc_metadata/cstore_impl.rs
New upstream version 1.14.0+dfsg1
[rustc.git] / src / librustc_metadata / cstore_impl.rs
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.
4 //
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.
10
11 use cstore;
12 use encoder;
13 use locator;
14 use schema;
15
16 use rustc::middle::cstore::{InlinedItem, CrateStore, CrateSource, ExternCrate};
17 use rustc::middle::cstore::{NativeLibraryKind, LinkMeta, LinkagePreference};
18 use rustc::hir::def::{self, Def};
19 use rustc::middle::lang_items;
20 use rustc::ty::{self, Ty, TyCtxt};
21 use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX};
22
23 use rustc::dep_graph::DepNode;
24 use rustc::hir::map as hir_map;
25 use rustc::hir::map::DefKey;
26 use rustc::mir::Mir;
27 use rustc::util::nodemap::{NodeSet, DefIdMap};
28 use rustc_back::PanicStrategy;
29
30 use std::path::PathBuf;
31 use syntax::ast;
32 use syntax::attr;
33 use syntax::parse::token;
34 use rustc::hir::svh::Svh;
35 use rustc_back::target::Target;
36 use rustc::hir;
37
38 impl<'tcx> CrateStore<'tcx> for cstore::CStore {
39 fn describe_def(&self, def: DefId) -> Option<Def> {
40 self.dep_graph.read(DepNode::MetaData(def));
41 self.get_crate_data(def.krate).get_def(def.index)
42 }
43
44 fn stability(&self, def: DefId) -> Option<attr::Stability> {
45 self.dep_graph.read(DepNode::MetaData(def));
46 self.get_crate_data(def.krate).get_stability(def.index)
47 }
48
49 fn deprecation(&self, def: DefId) -> Option<attr::Deprecation> {
50 self.dep_graph.read(DepNode::MetaData(def));
51 self.get_crate_data(def.krate).get_deprecation(def.index)
52 }
53
54 fn visibility(&self, def: DefId) -> ty::Visibility {
55 self.dep_graph.read(DepNode::MetaData(def));
56 self.get_crate_data(def.krate).get_visibility(def.index)
57 }
58
59 fn closure_kind(&self, def_id: DefId) -> ty::ClosureKind
60 {
61 assert!(!def_id.is_local());
62 self.dep_graph.read(DepNode::MetaData(def_id));
63 self.get_crate_data(def_id.krate).closure_kind(def_id.index)
64 }
65
66 fn closure_ty<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::ClosureTy<'tcx> {
67 assert!(!def_id.is_local());
68 self.dep_graph.read(DepNode::MetaData(def_id));
69 self.get_crate_data(def_id.krate).closure_ty(def_id.index, tcx)
70 }
71
72 fn item_variances(&self, def: DefId) -> Vec<ty::Variance> {
73 self.dep_graph.read(DepNode::MetaData(def));
74 self.get_crate_data(def.krate).get_item_variances(def.index)
75 }
76
77 fn item_type<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
78 -> Ty<'tcx>
79 {
80 self.dep_graph.read(DepNode::MetaData(def));
81 self.get_crate_data(def.krate).get_type(def.index, tcx)
82 }
83
84 fn item_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
85 -> ty::GenericPredicates<'tcx>
86 {
87 self.dep_graph.read(DepNode::MetaData(def));
88 self.get_crate_data(def.krate).get_predicates(def.index, tcx)
89 }
90
91 fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
92 -> ty::GenericPredicates<'tcx>
93 {
94 self.dep_graph.read(DepNode::MetaData(def));
95 self.get_crate_data(def.krate).get_super_predicates(def.index, tcx)
96 }
97
98 fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
99 -> ty::Generics<'tcx>
100 {
101 self.dep_graph.read(DepNode::MetaData(def));
102 self.get_crate_data(def.krate).get_generics(def.index, tcx)
103 }
104
105 fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>
106 {
107 self.dep_graph.read(DepNode::MetaData(def_id));
108 self.get_crate_data(def_id.krate).get_item_attrs(def_id.index)
109 }
110
111 fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::TraitDef<'tcx>
112 {
113 self.dep_graph.read(DepNode::MetaData(def));
114 self.get_crate_data(def.krate).get_trait_def(def.index, tcx)
115 }
116
117 fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>
118 {
119 self.dep_graph.read(DepNode::MetaData(def));
120 self.get_crate_data(def.krate).get_adt_def(def.index, tcx)
121 }
122
123 fn fn_arg_names(&self, did: DefId) -> Vec<ast::Name>
124 {
125 self.dep_graph.read(DepNode::MetaData(did));
126 self.get_crate_data(did.krate).get_fn_arg_names(did.index)
127 }
128
129 fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId>
130 {
131 self.dep_graph.read(DepNode::MetaData(def_id));
132 self.get_crate_data(def_id.krate).get_inherent_implementations_for_type(def_id.index)
133 }
134
135 fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId>
136 {
137 if let Some(def_id) = filter {
138 self.dep_graph.read(DepNode::MetaData(def_id));
139 }
140 let mut result = vec![];
141 self.iter_crate_data(|_, cdata| {
142 cdata.get_implementations_for_trait(filter, &mut result)
143 });
144 result
145 }
146
147 fn impl_or_trait_items(&self, def_id: DefId) -> Vec<DefId> {
148 self.dep_graph.read(DepNode::MetaData(def_id));
149 let mut result = vec![];
150 self.get_crate_data(def_id.krate)
151 .each_child_of_item(def_id.index, |child| result.push(child.def.def_id()));
152 result
153 }
154
155 fn impl_polarity(&self, def: DefId) -> hir::ImplPolarity
156 {
157 self.dep_graph.read(DepNode::MetaData(def));
158 self.get_crate_data(def.krate).get_impl_polarity(def.index)
159 }
160
161 fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
162 -> Option<ty::TraitRef<'tcx>>
163 {
164 self.dep_graph.read(DepNode::MetaData(def));
165 self.get_crate_data(def.krate).get_impl_trait(def.index, tcx)
166 }
167
168 fn custom_coerce_unsized_kind(&self, def: DefId)
169 -> Option<ty::adjustment::CustomCoerceUnsized>
170 {
171 self.dep_graph.read(DepNode::MetaData(def));
172 self.get_crate_data(def.krate).get_custom_coerce_unsized_kind(def.index)
173 }
174
175 fn impl_parent(&self, impl_def: DefId) -> Option<DefId> {
176 self.dep_graph.read(DepNode::MetaData(impl_def));
177 self.get_crate_data(impl_def.krate).get_parent_impl(impl_def.index)
178 }
179
180 fn trait_of_item(&self, def_id: DefId) -> Option<DefId> {
181 self.dep_graph.read(DepNode::MetaData(def_id));
182 self.get_crate_data(def_id.krate).get_trait_of_item(def_id.index)
183 }
184
185 fn impl_or_trait_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
186 -> Option<ty::ImplOrTraitItem<'tcx>>
187 {
188 self.dep_graph.read(DepNode::MetaData(def));
189 self.get_crate_data(def.krate).get_impl_or_trait_item(def.index, tcx)
190 }
191
192 fn is_const_fn(&self, did: DefId) -> bool
193 {
194 self.dep_graph.read(DepNode::MetaData(did));
195 self.get_crate_data(did.krate).is_const_fn(did.index)
196 }
197
198 fn is_defaulted_trait(&self, trait_def_id: DefId) -> bool
199 {
200 self.dep_graph.read(DepNode::MetaData(trait_def_id));
201 self.get_crate_data(trait_def_id.krate).is_defaulted_trait(trait_def_id.index)
202 }
203
204 fn is_default_impl(&self, impl_did: DefId) -> bool {
205 self.dep_graph.read(DepNode::MetaData(impl_did));
206 self.get_crate_data(impl_did.krate).is_default_impl(impl_did.index)
207 }
208
209 fn is_foreign_item(&self, did: DefId) -> bool {
210 self.get_crate_data(did.krate).is_foreign_item(did.index)
211 }
212
213 fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool
214 {
215 self.do_is_statically_included_foreign_item(id)
216 }
217
218 fn dylib_dependency_formats(&self, cnum: CrateNum)
219 -> Vec<(CrateNum, LinkagePreference)>
220 {
221 self.get_crate_data(cnum).get_dylib_dependency_formats()
222 }
223
224 fn lang_items(&self, cnum: CrateNum) -> Vec<(DefIndex, usize)>
225 {
226 self.get_crate_data(cnum).get_lang_items()
227 }
228
229 fn missing_lang_items(&self, cnum: CrateNum)
230 -> Vec<lang_items::LangItem>
231 {
232 self.get_crate_data(cnum).get_missing_lang_items()
233 }
234
235 fn is_staged_api(&self, cnum: CrateNum) -> bool
236 {
237 self.get_crate_data(cnum).is_staged_api()
238 }
239
240 fn is_explicitly_linked(&self, cnum: CrateNum) -> bool
241 {
242 self.get_crate_data(cnum).explicitly_linked.get()
243 }
244
245 fn is_allocator(&self, cnum: CrateNum) -> bool
246 {
247 self.get_crate_data(cnum).is_allocator()
248 }
249
250 fn is_panic_runtime(&self, cnum: CrateNum) -> bool
251 {
252 self.get_crate_data(cnum).is_panic_runtime()
253 }
254
255 fn is_compiler_builtins(&self, cnum: CrateNum) -> bool {
256 self.get_crate_data(cnum).is_compiler_builtins()
257 }
258
259 fn panic_strategy(&self, cnum: CrateNum) -> PanicStrategy {
260 self.get_crate_data(cnum).panic_strategy()
261 }
262
263 fn crate_name(&self, cnum: CrateNum) -> token::InternedString
264 {
265 token::intern_and_get_ident(&self.get_crate_data(cnum).name[..])
266 }
267
268 fn original_crate_name(&self, cnum: CrateNum) -> token::InternedString
269 {
270 token::intern_and_get_ident(&self.get_crate_data(cnum).name())
271 }
272
273 fn extern_crate(&self, cnum: CrateNum) -> Option<ExternCrate>
274 {
275 self.get_crate_data(cnum).extern_crate.get()
276 }
277
278 fn crate_hash(&self, cnum: CrateNum) -> Svh
279 {
280 self.get_crate_hash(cnum)
281 }
282
283 fn crate_disambiguator(&self, cnum: CrateNum) -> token::InternedString
284 {
285 token::intern_and_get_ident(&self.get_crate_data(cnum).disambiguator())
286 }
287
288 fn plugin_registrar_fn(&self, cnum: CrateNum) -> Option<DefId>
289 {
290 self.get_crate_data(cnum).root.plugin_registrar_fn.map(|index| DefId {
291 krate: cnum,
292 index: index
293 })
294 }
295
296 fn native_libraries(&self, cnum: CrateNum) -> Vec<(NativeLibraryKind, String)>
297 {
298 self.get_crate_data(cnum).get_native_libraries()
299 }
300
301 fn reachable_ids(&self, cnum: CrateNum) -> Vec<DefId>
302 {
303 self.get_crate_data(cnum).get_reachable_ids()
304 }
305
306 fn is_no_builtins(&self, cnum: CrateNum) -> bool {
307 self.get_crate_data(cnum).is_no_builtins()
308 }
309
310 fn def_index_for_def_key(&self,
311 cnum: CrateNum,
312 def: DefKey)
313 -> Option<DefIndex> {
314 let cdata = self.get_crate_data(cnum);
315 cdata.key_map.get(&def).cloned()
316 }
317
318 /// Returns the `DefKey` for a given `DefId`. This indicates the
319 /// parent `DefId` as well as some idea of what kind of data the
320 /// `DefId` refers to.
321 fn def_key(&self, def: DefId) -> hir_map::DefKey {
322 // Note: loading the def-key (or def-path) for a def-id is not
323 // a *read* of its metadata. This is because the def-id is
324 // really just an interned shorthand for a def-path, which is the
325 // canonical name for an item.
326 //
327 // self.dep_graph.read(DepNode::MetaData(def));
328 self.get_crate_data(def.krate).def_key(def.index)
329 }
330
331 fn relative_def_path(&self, def: DefId) -> Option<hir_map::DefPath> {
332 // See `Note` above in `def_key()` for why this read is
333 // commented out:
334 //
335 // self.dep_graph.read(DepNode::MetaData(def));
336 self.get_crate_data(def.krate).def_path(def.index)
337 }
338
339 fn struct_field_names(&self, def: DefId) -> Vec<ast::Name>
340 {
341 self.dep_graph.read(DepNode::MetaData(def));
342 self.get_crate_data(def.krate).get_struct_field_names(def.index)
343 }
344
345 fn item_children(&self, def_id: DefId) -> Vec<def::Export>
346 {
347 self.dep_graph.read(DepNode::MetaData(def_id));
348 let mut result = vec![];
349 self.get_crate_data(def_id.krate)
350 .each_child_of_item(def_id.index, |child| result.push(child));
351 result
352 }
353
354 fn maybe_get_item_ast<'a>(&'tcx self,
355 tcx: TyCtxt<'a, 'tcx, 'tcx>,
356 def_id: DefId)
357 -> Option<(&'tcx InlinedItem, ast::NodeId)>
358 {
359 self.dep_graph.read(DepNode::MetaData(def_id));
360
361 match self.inlined_item_cache.borrow().get(&def_id) {
362 Some(&None) => {
363 return None; // Not inlinable
364 }
365 Some(&Some(ref cached_inlined_item)) => {
366 // Already inline
367 debug!("maybe_get_item_ast({}): already inline as node id {}",
368 tcx.item_path_str(def_id), cached_inlined_item.item_id);
369 return Some((tcx.map.expect_inlined_item(cached_inlined_item.inlined_root),
370 cached_inlined_item.item_id));
371 }
372 None => {
373 // Not seen yet
374 }
375 }
376
377 debug!("maybe_get_item_ast({}): inlining item", tcx.item_path_str(def_id));
378
379 let inlined = self.get_crate_data(def_id.krate).maybe_get_item_ast(tcx, def_id.index);
380
381 let cache_inlined_item = |original_def_id, inlined_item_id, inlined_root_node_id| {
382 let cache_entry = cstore::CachedInlinedItem {
383 inlined_root: inlined_root_node_id,
384 item_id: inlined_item_id,
385 };
386 self.inlined_item_cache
387 .borrow_mut()
388 .insert(original_def_id, Some(cache_entry));
389 self.defid_for_inlined_node
390 .borrow_mut()
391 .insert(inlined_item_id, original_def_id);
392 };
393
394 let find_inlined_item_root = |inlined_item_id| {
395 let mut node = inlined_item_id;
396 let mut path = Vec::with_capacity(10);
397
398 // If we can't find the inline root after a thousand hops, we can
399 // be pretty sure there's something wrong with the HIR map.
400 for _ in 0 .. 1000 {
401 path.push(node);
402 let parent_node = tcx.map.get_parent_node(node);
403 if parent_node == node {
404 return node;
405 }
406 node = parent_node;
407 }
408 bug!("cycle in HIR map parent chain")
409 };
410
411 match inlined {
412 None => {
413 self.inlined_item_cache
414 .borrow_mut()
415 .insert(def_id, None);
416 }
417 Some(&InlinedItem::Item(d, ref item)) => {
418 assert_eq!(d, def_id);
419 let inlined_root_node_id = find_inlined_item_root(item.id);
420 cache_inlined_item(def_id, item.id, inlined_root_node_id);
421 }
422 Some(&InlinedItem::TraitItem(_, ref trait_item)) => {
423 let inlined_root_node_id = find_inlined_item_root(trait_item.id);
424 cache_inlined_item(def_id, trait_item.id, inlined_root_node_id);
425
426 // Associated consts already have to be evaluated in `typeck`, so
427 // the logic to do that already exists in `middle`. In order to
428 // reuse that code, it needs to be able to look up the traits for
429 // inlined items.
430 let ty_trait_item = tcx.impl_or_trait_item(def_id).clone();
431 let trait_item_def_id = tcx.map.local_def_id(trait_item.id);
432 tcx.impl_or_trait_items.borrow_mut()
433 .insert(trait_item_def_id, ty_trait_item);
434 }
435 Some(&InlinedItem::ImplItem(_, ref impl_item)) => {
436 let inlined_root_node_id = find_inlined_item_root(impl_item.id);
437 cache_inlined_item(def_id, impl_item.id, inlined_root_node_id);
438 }
439 }
440
441 // We can be sure to hit the cache now
442 return self.maybe_get_item_ast(tcx, def_id);
443 }
444
445 fn local_node_for_inlined_defid(&'tcx self, def_id: DefId) -> Option<ast::NodeId> {
446 assert!(!def_id.is_local());
447 match self.inlined_item_cache.borrow().get(&def_id) {
448 Some(&Some(ref cached_inlined_item)) => {
449 Some(cached_inlined_item.item_id)
450 }
451 Some(&None) => {
452 None
453 }
454 _ => {
455 bug!("Trying to lookup inlined NodeId for unexpected item");
456 }
457 }
458 }
459
460 fn defid_for_inlined_node(&'tcx self, node_id: ast::NodeId) -> Option<DefId> {
461 self.defid_for_inlined_node.borrow().get(&node_id).map(|x| *x)
462 }
463
464 fn get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Mir<'tcx> {
465 self.dep_graph.read(DepNode::MetaData(def));
466 self.get_crate_data(def.krate).maybe_get_item_mir(tcx, def.index).unwrap_or_else(|| {
467 bug!("get_item_mir: missing MIR for {}", tcx.item_path_str(def))
468 })
469 }
470
471 fn is_item_mir_available(&self, def: DefId) -> bool {
472 self.dep_graph.read(DepNode::MetaData(def));
473 self.get_crate_data(def.krate).is_item_mir_available(def.index)
474 }
475
476 fn crates(&self) -> Vec<CrateNum>
477 {
478 let mut result = vec![];
479 self.iter_crate_data(|cnum, _| result.push(cnum));
480 result
481 }
482
483 fn used_libraries(&self) -> Vec<(String, NativeLibraryKind)>
484 {
485 self.get_used_libraries().borrow().clone()
486 }
487
488 fn used_link_args(&self) -> Vec<String>
489 {
490 self.get_used_link_args().borrow().clone()
491 }
492
493 fn metadata_filename(&self) -> &str
494 {
495 locator::METADATA_FILENAME
496 }
497
498 fn metadata_section_name(&self, target: &Target) -> &str
499 {
500 locator::meta_section_name(target)
501 }
502
503 fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, Option<PathBuf>)>
504 {
505 self.do_get_used_crates(prefer)
506 }
507
508 fn used_crate_source(&self, cnum: CrateNum) -> CrateSource
509 {
510 self.opt_used_crate_source(cnum).unwrap()
511 }
512
513 fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum>
514 {
515 self.do_extern_mod_stmt_cnum(emod_id)
516 }
517
518 fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
519 reexports: &def::ExportMap,
520 link_meta: &LinkMeta,
521 reachable: &NodeSet) -> Vec<u8>
522 {
523 encoder::encode_metadata(tcx, self, reexports, link_meta, reachable)
524 }
525
526 fn metadata_encoding_version(&self) -> &[u8]
527 {
528 schema::METADATA_HEADER
529 }
530
531 /// Returns a map from a sufficiently visible external item (i.e. an external item that is
532 /// visible from at least one local module) to a sufficiently visible parent (considering
533 /// modules that re-export the external item to be parents).
534 fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>> {
535 let mut visible_parent_map = self.visible_parent_map.borrow_mut();
536 if !visible_parent_map.is_empty() { return visible_parent_map; }
537
538 use std::collections::vec_deque::VecDeque;
539 use std::collections::hash_map::Entry;
540 for cnum in (1 .. self.next_crate_num().as_usize()).map(CrateNum::new) {
541 let cdata = self.get_crate_data(cnum);
542
543 match cdata.extern_crate.get() {
544 // Ignore crates without a corresponding local `extern crate` item.
545 Some(extern_crate) if !extern_crate.direct => continue,
546 _ => {},
547 }
548
549 let mut bfs_queue = &mut VecDeque::new();
550 let mut add_child = |bfs_queue: &mut VecDeque<_>, child: def::Export, parent: DefId| {
551 let child = child.def.def_id();
552
553 if self.visibility(child) != ty::Visibility::Public {
554 return;
555 }
556
557 match visible_parent_map.entry(child) {
558 Entry::Occupied(mut entry) => {
559 // If `child` is defined in crate `cnum`, ensure
560 // that it is mapped to a parent in `cnum`.
561 if child.krate == cnum && entry.get().krate != cnum {
562 entry.insert(parent);
563 }
564 }
565 Entry::Vacant(entry) => {
566 entry.insert(parent);
567 bfs_queue.push_back(child);
568 }
569 }
570 };
571
572 bfs_queue.push_back(DefId {
573 krate: cnum,
574 index: CRATE_DEF_INDEX
575 });
576 while let Some(def) = bfs_queue.pop_front() {
577 for child in self.item_children(def) {
578 add_child(bfs_queue, child, def);
579 }
580 }
581 }
582
583 visible_parent_map
584 }
585 }