]> git.lizzy.rs Git - rust.git/blob - src/librustc_metadata/csearch.rs
Changed issue number to 36105
[rust.git] / src / librustc_metadata / csearch.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 common;
13 use decoder;
14 use encoder;
15 use loader;
16
17 use middle::cstore::{InlinedItem, CrateStore, CrateSource, ChildItem, ExternCrate, DefLike};
18 use middle::cstore::{NativeLibraryKind, LinkMeta, LinkagePreference};
19 use rustc::hir::def;
20 use middle::lang_items;
21 use rustc::ty::{self, Ty, TyCtxt, VariantKind};
22 use rustc::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
23
24 use rustc::dep_graph::DepNode;
25 use rustc::hir::map as hir_map;
26 use rustc::hir::map::DefKey;
27 use rustc::mir::repr::Mir;
28 use rustc::mir::mir_map::MirMap;
29 use rustc::util::nodemap::{FnvHashMap, NodeSet, DefIdMap};
30 use rustc::session::config::PanicStrategy;
31
32 use std::cell::RefCell;
33 use std::rc::Rc;
34 use std::path::PathBuf;
35 use syntax::ast;
36 use syntax::attr;
37 use syntax::parse::token;
38 use rustc::hir::svh::Svh;
39 use rustc_back::target::Target;
40 use rustc::hir;
41
42 impl<'tcx> CrateStore<'tcx> for cstore::CStore {
43     fn stability(&self, def: DefId) -> Option<attr::Stability> {
44         self.dep_graph.read(DepNode::MetaData(def));
45         let cdata = self.get_crate_data(def.krate);
46         decoder::get_stability(&cdata, def.index)
47     }
48
49     fn deprecation(&self, def: DefId) -> Option<attr::Deprecation> {
50         self.dep_graph.read(DepNode::MetaData(def));
51         let cdata = self.get_crate_data(def.krate);
52         decoder::get_deprecation(&cdata, def.index)
53     }
54
55     fn visibility(&self, def: DefId) -> ty::Visibility {
56         self.dep_graph.read(DepNode::MetaData(def));
57         let cdata = self.get_crate_data(def.krate);
58         decoder::get_visibility(&cdata, def.index)
59     }
60
61     fn closure_kind(&self, def_id: DefId) -> ty::ClosureKind
62     {
63         assert!(!def_id.is_local());
64         self.dep_graph.read(DepNode::MetaData(def_id));
65         let cdata = self.get_crate_data(def_id.krate);
66         decoder::closure_kind(&cdata, def_id.index)
67     }
68
69     fn closure_ty<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::ClosureTy<'tcx> {
70         assert!(!def_id.is_local());
71         self.dep_graph.read(DepNode::MetaData(def_id));
72         let cdata = self.get_crate_data(def_id.krate);
73         decoder::closure_ty(&cdata, def_id.index, tcx)
74     }
75
76     fn item_variances(&self, def: DefId) -> ty::ItemVariances {
77         self.dep_graph.read(DepNode::MetaData(def));
78         let cdata = self.get_crate_data(def.krate);
79         decoder::get_item_variances(&cdata, def.index)
80     }
81
82     fn repr_attrs(&self, def: DefId) -> Vec<attr::ReprAttr> {
83         self.dep_graph.read(DepNode::MetaData(def));
84         let cdata = self.get_crate_data(def.krate);
85         decoder::get_repr_attrs(&cdata, def.index)
86     }
87
88     fn item_type<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
89                      -> Ty<'tcx>
90     {
91         self.dep_graph.read(DepNode::MetaData(def));
92         let cdata = self.get_crate_data(def.krate);
93         decoder::get_type(&cdata, def.index, tcx)
94     }
95
96     fn item_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
97                            -> ty::GenericPredicates<'tcx>
98     {
99         self.dep_graph.read(DepNode::MetaData(def));
100         let cdata = self.get_crate_data(def.krate);
101         decoder::get_predicates(&cdata, def.index, tcx)
102     }
103
104     fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
105                                  -> ty::GenericPredicates<'tcx>
106     {
107         self.dep_graph.read(DepNode::MetaData(def));
108         let cdata = self.get_crate_data(def.krate);
109         decoder::get_super_predicates(&cdata, def.index, tcx)
110     }
111
112     fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
113                          -> &'tcx ty::Generics<'tcx>
114     {
115         self.dep_graph.read(DepNode::MetaData(def));
116         let cdata = self.get_crate_data(def.krate);
117         decoder::get_generics(&cdata, def.index, tcx)
118     }
119
120     fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>
121     {
122         self.dep_graph.read(DepNode::MetaData(def_id));
123         let cdata = self.get_crate_data(def_id.krate);
124         decoder::get_item_attrs(&cdata, def_id.index)
125     }
126
127     fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::TraitDef<'tcx>
128     {
129         self.dep_graph.read(DepNode::MetaData(def));
130         let cdata = self.get_crate_data(def.krate);
131         decoder::get_trait_def(&cdata, def.index, tcx)
132     }
133
134     fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>
135     {
136         self.dep_graph.read(DepNode::MetaData(def));
137         let cdata = self.get_crate_data(def.krate);
138         decoder::get_adt_def(&cdata, def.index, tcx)
139     }
140
141     fn method_arg_names(&self, did: DefId) -> Vec<String>
142     {
143         self.dep_graph.read(DepNode::MetaData(did));
144         let cdata = self.get_crate_data(did.krate);
145         decoder::get_method_arg_names(&cdata, did.index)
146     }
147
148     fn item_name(&self, def: DefId) -> ast::Name {
149         self.dep_graph.read(DepNode::MetaData(def));
150         let cdata = self.get_crate_data(def.krate);
151         decoder::get_item_name(&cdata, def.index)
152     }
153
154     fn opt_item_name(&self, def: DefId) -> Option<ast::Name> {
155         self.dep_graph.read(DepNode::MetaData(def));
156         let cdata = self.get_crate_data(def.krate);
157         decoder::maybe_get_item_name(&cdata, def.index)
158     }
159
160     fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId>
161     {
162         self.dep_graph.read(DepNode::MetaData(def_id));
163         let mut result = vec![];
164         let cdata = self.get_crate_data(def_id.krate);
165         decoder::each_inherent_implementation_for_type(&cdata, def_id.index,
166                                                        |iid| result.push(iid));
167         result
168     }
169
170     fn implementations_of_trait(&self, def_id: DefId) -> Vec<DefId>
171     {
172         self.dep_graph.read(DepNode::MetaData(def_id));
173         let mut result = vec![];
174         self.iter_crate_data(|_, cdata| {
175             decoder::each_implementation_for_trait(cdata, def_id, &mut |iid| {
176                 result.push(iid)
177             })
178         });
179         result
180     }
181
182     fn provided_trait_methods<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
183                                   -> Vec<Rc<ty::Method<'tcx>>>
184     {
185         self.dep_graph.read(DepNode::MetaData(def));
186         let cdata = self.get_crate_data(def.krate);
187         decoder::get_provided_trait_methods(&cdata, def.index, tcx)
188     }
189
190     fn trait_item_def_ids(&self, def: DefId)
191                           -> Vec<ty::ImplOrTraitItemId>
192     {
193         self.dep_graph.read(DepNode::MetaData(def));
194         let cdata = self.get_crate_data(def.krate);
195         decoder::get_trait_item_def_ids(&cdata, def.index)
196     }
197
198     fn impl_items(&self, impl_def_id: DefId) -> Vec<ty::ImplOrTraitItemId>
199     {
200         self.dep_graph.read(DepNode::MetaData(impl_def_id));
201         let cdata = self.get_crate_data(impl_def_id.krate);
202         decoder::get_impl_items(&cdata, impl_def_id.index)
203     }
204
205     fn impl_polarity(&self, def: DefId) -> Option<hir::ImplPolarity>
206     {
207         self.dep_graph.read(DepNode::MetaData(def));
208         let cdata = self.get_crate_data(def.krate);
209         decoder::get_impl_polarity(&cdata, def.index)
210     }
211
212     fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
213                           -> Option<ty::TraitRef<'tcx>>
214     {
215         self.dep_graph.read(DepNode::MetaData(def));
216         let cdata = self.get_crate_data(def.krate);
217         decoder::get_impl_trait(&cdata, def.index, tcx)
218     }
219
220     fn custom_coerce_unsized_kind(&self, def: DefId)
221                                   -> Option<ty::adjustment::CustomCoerceUnsized>
222     {
223         self.dep_graph.read(DepNode::MetaData(def));
224         let cdata = self.get_crate_data(def.krate);
225         decoder::get_custom_coerce_unsized_kind(&cdata, def.index)
226     }
227
228     // FIXME: killme
229     fn associated_consts<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
230                              -> Vec<Rc<ty::AssociatedConst<'tcx>>> {
231         self.dep_graph.read(DepNode::MetaData(def));
232         let cdata = self.get_crate_data(def.krate);
233         decoder::get_associated_consts(&cdata, def.index, tcx)
234     }
235
236     fn impl_parent(&self, impl_def: DefId) -> Option<DefId> {
237         self.dep_graph.read(DepNode::MetaData(impl_def));
238         let cdata = self.get_crate_data(impl_def.krate);
239         decoder::get_parent_impl(&*cdata, impl_def.index)
240     }
241
242     fn trait_of_item(&self, def_id: DefId) -> Option<DefId> {
243         self.dep_graph.read(DepNode::MetaData(def_id));
244         let cdata = self.get_crate_data(def_id.krate);
245         decoder::get_trait_of_item(&cdata, def_id.index)
246     }
247
248     fn impl_or_trait_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
249                               -> Option<ty::ImplOrTraitItem<'tcx>>
250     {
251         self.dep_graph.read(DepNode::MetaData(def));
252         let cdata = self.get_crate_data(def.krate);
253         decoder::get_impl_or_trait_item(&cdata, def.index, tcx)
254     }
255
256     fn is_const_fn(&self, did: DefId) -> bool
257     {
258         self.dep_graph.read(DepNode::MetaData(did));
259         let cdata = self.get_crate_data(did.krate);
260         decoder::is_const_fn(&cdata, did.index)
261     }
262
263     fn is_defaulted_trait(&self, trait_def_id: DefId) -> bool
264     {
265         self.dep_graph.read(DepNode::MetaData(trait_def_id));
266         let cdata = self.get_crate_data(trait_def_id.krate);
267         decoder::is_defaulted_trait(&cdata, trait_def_id.index)
268     }
269
270     fn is_impl(&self, did: DefId) -> bool
271     {
272         self.dep_graph.read(DepNode::MetaData(did));
273         let cdata = self.get_crate_data(did.krate);
274         decoder::is_impl(&cdata, did.index)
275     }
276
277     fn is_default_impl(&self, impl_did: DefId) -> bool {
278         self.dep_graph.read(DepNode::MetaData(impl_did));
279         let cdata = self.get_crate_data(impl_did.krate);
280         decoder::is_default_impl(&cdata, impl_did.index)
281     }
282
283     fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool {
284         self.dep_graph.read(DepNode::MetaData(did));
285         let cdata = self.get_crate_data(did.krate);
286         decoder::is_extern_item(&cdata, did.index, tcx)
287     }
288
289     fn is_foreign_item(&self, did: DefId) -> bool {
290         let cdata = self.get_crate_data(did.krate);
291         decoder::is_foreign_item(&cdata, did.index)
292     }
293
294     fn is_static_method(&self, def: DefId) -> bool
295     {
296         self.dep_graph.read(DepNode::MetaData(def));
297         let cdata = self.get_crate_data(def.krate);
298         decoder::is_static_method(&cdata, def.index)
299     }
300
301     fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool
302     {
303         self.do_is_statically_included_foreign_item(id)
304     }
305
306     fn is_typedef(&self, did: DefId) -> bool {
307         self.dep_graph.read(DepNode::MetaData(did));
308         let cdata = self.get_crate_data(did.krate);
309         decoder::is_typedef(&cdata, did.index)
310     }
311
312     fn dylib_dependency_formats(&self, cnum: ast::CrateNum)
313                                 -> Vec<(ast::CrateNum, LinkagePreference)>
314     {
315         let cdata = self.get_crate_data(cnum);
316         decoder::get_dylib_dependency_formats(&cdata)
317     }
318
319     fn lang_items(&self, cnum: ast::CrateNum) -> Vec<(DefIndex, usize)>
320     {
321         let mut result = vec![];
322         let crate_data = self.get_crate_data(cnum);
323         decoder::each_lang_item(&crate_data, |did, lid| {
324             result.push((did, lid)); true
325         });
326         result
327     }
328
329     fn missing_lang_items(&self, cnum: ast::CrateNum)
330                           -> Vec<lang_items::LangItem>
331     {
332         let cdata = self.get_crate_data(cnum);
333         decoder::get_missing_lang_items(&cdata)
334     }
335
336     fn is_staged_api(&self, cnum: ast::CrateNum) -> bool
337     {
338         self.get_crate_data(cnum).staged_api
339     }
340
341     fn is_explicitly_linked(&self, cnum: ast::CrateNum) -> bool
342     {
343         self.get_crate_data(cnum).explicitly_linked.get()
344     }
345
346     fn is_allocator(&self, cnum: ast::CrateNum) -> bool
347     {
348         self.get_crate_data(cnum).is_allocator()
349     }
350
351     fn is_panic_runtime(&self, cnum: ast::CrateNum) -> bool
352     {
353         self.get_crate_data(cnum).is_panic_runtime()
354     }
355
356     fn panic_strategy(&self, cnum: ast::CrateNum) -> PanicStrategy {
357         self.get_crate_data(cnum).panic_strategy()
358     }
359
360     fn crate_attrs(&self, cnum: ast::CrateNum) -> Vec<ast::Attribute>
361     {
362         decoder::get_crate_attributes(self.get_crate_data(cnum).data())
363     }
364
365     fn crate_name(&self, cnum: ast::CrateNum) -> token::InternedString
366     {
367         token::intern_and_get_ident(&self.get_crate_data(cnum).name[..])
368     }
369
370     fn original_crate_name(&self, cnum: ast::CrateNum) -> token::InternedString
371     {
372         token::intern_and_get_ident(&self.get_crate_data(cnum).name())
373     }
374
375     fn extern_crate(&self, cnum: ast::CrateNum) -> Option<ExternCrate>
376     {
377         self.get_crate_data(cnum).extern_crate.get()
378     }
379
380     fn crate_hash(&self, cnum: ast::CrateNum) -> Svh
381     {
382         let cdata = self.get_crate_data(cnum);
383         decoder::get_crate_hash(cdata.data())
384     }
385
386     fn crate_disambiguator(&self, cnum: ast::CrateNum) -> token::InternedString
387     {
388         let cdata = self.get_crate_data(cnum);
389         token::intern_and_get_ident(decoder::get_crate_disambiguator(cdata.data()))
390     }
391
392     fn crate_struct_field_attrs(&self, cnum: ast::CrateNum)
393                                 -> FnvHashMap<DefId, Vec<ast::Attribute>>
394     {
395         decoder::get_struct_field_attrs(&self.get_crate_data(cnum))
396     }
397
398     fn plugin_registrar_fn(&self, cnum: ast::CrateNum) -> Option<DefId>
399     {
400         let cdata = self.get_crate_data(cnum);
401         decoder::get_plugin_registrar_fn(cdata.data()).map(|index| DefId {
402             krate: cnum,
403             index: index
404         })
405     }
406
407     fn native_libraries(&self, cnum: ast::CrateNum) -> Vec<(NativeLibraryKind, String)>
408     {
409         let cdata = self.get_crate_data(cnum);
410         decoder::get_native_libraries(&cdata)
411     }
412
413     fn reachable_ids(&self, cnum: ast::CrateNum) -> Vec<DefId>
414     {
415         let cdata = self.get_crate_data(cnum);
416         decoder::get_reachable_ids(&cdata)
417     }
418
419     fn is_no_builtins(&self, cnum: ast::CrateNum) -> bool {
420         attr::contains_name(&self.crate_attrs(cnum), "no_builtins")
421     }
422
423     fn def_index_for_def_key(&self,
424                              cnum: ast::CrateNum,
425                              def: DefKey)
426                              -> Option<DefIndex> {
427         let cdata = self.get_crate_data(cnum);
428         cdata.key_map.get(&def).cloned()
429     }
430
431     /// Returns the `DefKey` for a given `DefId`. This indicates the
432     /// parent `DefId` as well as some idea of what kind of data the
433     /// `DefId` refers to.
434     fn def_key(&self, def: DefId) -> hir_map::DefKey {
435         self.dep_graph.read(DepNode::MetaData(def));
436         let cdata = self.get_crate_data(def.krate);
437         decoder::def_key(&cdata, def.index)
438     }
439
440     fn relative_def_path(&self, def: DefId) -> hir_map::DefPath {
441         self.dep_graph.read(DepNode::MetaData(def));
442         let cdata = self.get_crate_data(def.krate);
443         decoder::def_path(&cdata, def.index)
444     }
445
446     fn variant_kind(&self, def_id: DefId) -> Option<VariantKind> {
447         self.dep_graph.read(DepNode::MetaData(def_id));
448         let cdata = self.get_crate_data(def_id.krate);
449         decoder::get_variant_kind(&cdata, def_id.index)
450     }
451
452     fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option<DefId>
453     {
454         self.dep_graph.read(DepNode::MetaData(struct_def_id));
455         let cdata = self.get_crate_data(struct_def_id.krate);
456         decoder::get_struct_ctor_def_id(&cdata, struct_def_id.index)
457     }
458
459     fn tuple_struct_definition_if_ctor(&self, did: DefId) -> Option<DefId>
460     {
461         self.dep_graph.read(DepNode::MetaData(did));
462         let cdata = self.get_crate_data(did.krate);
463         decoder::get_tuple_struct_definition_if_ctor(&cdata, did.index)
464     }
465
466     fn struct_field_names(&self, def: DefId) -> Vec<ast::Name>
467     {
468         self.dep_graph.read(DepNode::MetaData(def));
469         let cdata = self.get_crate_data(def.krate);
470         decoder::get_struct_field_names(&cdata, def.index)
471     }
472
473     fn item_children(&self, def_id: DefId) -> Vec<ChildItem>
474     {
475         self.dep_graph.read(DepNode::MetaData(def_id));
476         let mut result = vec![];
477         let crate_data = self.get_crate_data(def_id.krate);
478         let get_crate_data = |cnum| self.get_crate_data(cnum);
479         decoder::each_child_of_item(&crate_data, def_id.index, get_crate_data, |def, name, vis| {
480             result.push(ChildItem { def: def, name: name, vis: vis });
481         });
482         result
483     }
484
485     fn crate_top_level_items(&self, cnum: ast::CrateNum) -> Vec<ChildItem>
486     {
487         let mut result = vec![];
488         let crate_data = self.get_crate_data(cnum);
489         let get_crate_data = |cnum| self.get_crate_data(cnum);
490         decoder::each_top_level_item_of_crate(&crate_data, get_crate_data, |def, name, vis| {
491             result.push(ChildItem { def: def, name: name, vis: vis });
492         });
493         result
494     }
495
496     fn maybe_get_item_ast<'a>(&'tcx self,
497                               tcx: TyCtxt<'a, 'tcx, 'tcx>,
498                               def_id: DefId)
499                               -> Option<(&'tcx InlinedItem, ast::NodeId)>
500     {
501         self.dep_graph.read(DepNode::MetaData(def_id));
502
503         match self.inlined_item_cache.borrow().get(&def_id) {
504             Some(&None) => {
505                 return None; // Not inlinable
506             }
507             Some(&Some(ref cached_inlined_item)) => {
508                 // Already inline
509                 debug!("maybe_get_item_ast({}): already inline as node id {}",
510                           tcx.item_path_str(def_id), cached_inlined_item.item_id);
511                 return Some((tcx.map.expect_inlined_item(cached_inlined_item.inlined_root),
512                              cached_inlined_item.item_id));
513             }
514             None => {
515                 // Not seen yet
516             }
517         }
518
519         debug!("maybe_get_item_ast({}): inlining item", tcx.item_path_str(def_id));
520
521         let cdata = self.get_crate_data(def_id.krate);
522         let inlined = decoder::maybe_get_item_ast(&cdata, tcx, def_id.index);
523
524         let cache_inlined_item = |original_def_id, inlined_item_id, inlined_root_node_id| {
525             let cache_entry = cstore::CachedInlinedItem {
526                 inlined_root: inlined_root_node_id,
527                 item_id: inlined_item_id,
528             };
529             self.inlined_item_cache
530                 .borrow_mut()
531                 .insert(original_def_id, Some(cache_entry));
532             self.defid_for_inlined_node
533                 .borrow_mut()
534                 .insert(inlined_item_id, original_def_id);
535         };
536
537         let find_inlined_item_root = |inlined_item_id| {
538             let mut node = inlined_item_id;
539             let mut path = Vec::with_capacity(10);
540
541             // If we can't find the inline root after a thousand hops, we can
542             // be pretty sure there's something wrong with the HIR map.
543             for _ in 0 .. 1000 {
544                 path.push(node);
545                 let parent_node = tcx.map.get_parent_node(node);
546                 if parent_node == node {
547                     return node;
548                 }
549                 node = parent_node;
550             }
551             bug!("cycle in HIR map parent chain")
552         };
553
554         match inlined {
555             decoder::FoundAst::NotFound => {
556                 self.inlined_item_cache
557                     .borrow_mut()
558                     .insert(def_id, None);
559             }
560             decoder::FoundAst::Found(&InlinedItem::Item(d, ref item)) => {
561                 assert_eq!(d, def_id);
562                 let inlined_root_node_id = find_inlined_item_root(item.id);
563                 cache_inlined_item(def_id, item.id, inlined_root_node_id);
564             }
565             decoder::FoundAst::Found(&InlinedItem::Foreign(d, ref item)) => {
566                 assert_eq!(d, def_id);
567                 let inlined_root_node_id = find_inlined_item_root(item.id);
568                 cache_inlined_item(def_id, item.id, inlined_root_node_id);
569             }
570             decoder::FoundAst::FoundParent(parent_did, item) => {
571                 let inlined_root_node_id = find_inlined_item_root(item.id);
572                 cache_inlined_item(parent_did, item.id, inlined_root_node_id);
573
574                 match item.node {
575                     hir::ItemEnum(ref ast_def, _) => {
576                         let ast_vs = &ast_def.variants;
577                         let ty_vs = &tcx.lookup_adt_def(parent_did).variants;
578                         assert_eq!(ast_vs.len(), ty_vs.len());
579                         for (ast_v, ty_v) in ast_vs.iter().zip(ty_vs.iter()) {
580                             cache_inlined_item(ty_v.did,
581                                                ast_v.node.data.id(),
582                                                inlined_root_node_id);
583                         }
584                     }
585                     hir::ItemStruct(ref struct_def, _) => {
586                         if struct_def.is_struct() {
587                             bug!("instantiate_inline: called on a non-tuple struct")
588                         } else {
589                             cache_inlined_item(def_id,
590                                                struct_def.id(),
591                                                inlined_root_node_id);
592                         }
593                     }
594                     _ => bug!("instantiate_inline: item has a \
595                                non-enum, non-struct parent")
596                 }
597             }
598             decoder::FoundAst::Found(&InlinedItem::TraitItem(_, ref trait_item)) => {
599                 let inlined_root_node_id = find_inlined_item_root(trait_item.id);
600                 cache_inlined_item(def_id, trait_item.id, inlined_root_node_id);
601
602                 // Associated consts already have to be evaluated in `typeck`, so
603                 // the logic to do that already exists in `middle`. In order to
604                 // reuse that code, it needs to be able to look up the traits for
605                 // inlined items.
606                 let ty_trait_item = tcx.impl_or_trait_item(def_id).clone();
607                 let trait_item_def_id = tcx.map.local_def_id(trait_item.id);
608                 tcx.impl_or_trait_items.borrow_mut()
609                    .insert(trait_item_def_id, ty_trait_item);
610             }
611             decoder::FoundAst::Found(&InlinedItem::ImplItem(_, ref impl_item)) => {
612                 let inlined_root_node_id = find_inlined_item_root(impl_item.id);
613                 cache_inlined_item(def_id, impl_item.id, inlined_root_node_id);
614             }
615         }
616
617         // We can be sure to hit the cache now
618         return self.maybe_get_item_ast(tcx, def_id);
619     }
620
621     fn local_node_for_inlined_defid(&'tcx self, def_id: DefId) -> Option<ast::NodeId> {
622         assert!(!def_id.is_local());
623         match self.inlined_item_cache.borrow().get(&def_id) {
624             Some(&Some(ref cached_inlined_item)) => {
625                 Some(cached_inlined_item.item_id)
626             }
627             Some(&None) => {
628                 None
629             }
630             _ => {
631                 bug!("Trying to lookup inlined NodeId for unexpected item");
632             }
633         }
634     }
635
636     fn defid_for_inlined_node(&'tcx self, node_id: ast::NodeId) -> Option<DefId> {
637         self.defid_for_inlined_node.borrow().get(&node_id).map(|x| *x)
638     }
639
640     fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
641                               -> Option<Mir<'tcx>> {
642         self.dep_graph.read(DepNode::MetaData(def));
643         let cdata = self.get_crate_data(def.krate);
644         decoder::maybe_get_item_mir(&cdata, tcx, def.index)
645     }
646
647     fn is_item_mir_available(&self, def: DefId) -> bool {
648         self.dep_graph.read(DepNode::MetaData(def));
649         let cdata = self.get_crate_data(def.krate);
650         decoder::is_item_mir_available(&cdata, def.index)
651     }
652
653     fn crates(&self) -> Vec<ast::CrateNum>
654     {
655         let mut result = vec![];
656         self.iter_crate_data(|cnum, _| result.push(cnum));
657         result
658     }
659
660     fn used_libraries(&self) -> Vec<(String, NativeLibraryKind)>
661     {
662         self.get_used_libraries().borrow().clone()
663     }
664
665     fn used_link_args(&self) -> Vec<String>
666     {
667         self.get_used_link_args().borrow().clone()
668     }
669
670     fn metadata_filename(&self) -> &str
671     {
672         loader::METADATA_FILENAME
673     }
674
675     fn metadata_section_name(&self, target: &Target) -> &str
676     {
677         loader::meta_section_name(target)
678     }
679     fn encode_type<'a>(&self,
680                        tcx: TyCtxt<'a, 'tcx, 'tcx>,
681                        ty: Ty<'tcx>,
682                        def_id_to_string: for<'b> fn(TyCtxt<'b, 'tcx, 'tcx>, DefId) -> String)
683                        -> Vec<u8>
684     {
685         encoder::encoded_ty(tcx, ty, def_id_to_string)
686     }
687
688     fn used_crates(&self, prefer: LinkagePreference) -> Vec<(ast::CrateNum, Option<PathBuf>)>
689     {
690         self.do_get_used_crates(prefer)
691     }
692
693     fn used_crate_source(&self, cnum: ast::CrateNum) -> CrateSource
694     {
695         self.opt_used_crate_source(cnum).unwrap()
696     }
697
698     fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<ast::CrateNum>
699     {
700         self.do_extern_mod_stmt_cnum(emod_id)
701     }
702
703     fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
704                            reexports: &def::ExportMap,
705                            link_meta: &LinkMeta,
706                            reachable: &NodeSet,
707                            mir_map: &MirMap<'tcx>,
708                            krate: &hir::Crate) -> Vec<u8>
709     {
710         let ecx = encoder::EncodeContext {
711             diag: tcx.sess.diagnostic(),
712             tcx: tcx,
713             reexports: reexports,
714             link_meta: link_meta,
715             cstore: self,
716             reachable: reachable,
717             mir_map: mir_map,
718             type_abbrevs: RefCell::new(FnvHashMap()),
719         };
720         encoder::encode_metadata(ecx, krate)
721
722     }
723
724     fn metadata_encoding_version(&self) -> &[u8]
725     {
726         common::metadata_encoding_version
727     }
728
729     /// Returns a map from a sufficiently visible external item (i.e. an external item that is
730     /// visible from at least one local module) to a sufficiently visible parent (considering
731     /// modules that re-export the external item to be parents).
732     fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>> {
733         let mut visible_parent_map = self.visible_parent_map.borrow_mut();
734         if !visible_parent_map.is_empty() { return visible_parent_map; }
735
736         use rustc::middle::cstore::ChildItem;
737         use std::collections::vec_deque::VecDeque;
738         use std::collections::hash_map::Entry;
739         for cnum in 1 .. self.next_crate_num() {
740             let cdata = self.get_crate_data(cnum);
741
742             match cdata.extern_crate.get() {
743                 // Ignore crates without a corresponding local `extern crate` item.
744                 Some(extern_crate) if !extern_crate.direct => continue,
745                 _ => {},
746             }
747
748             let mut bfs_queue = &mut VecDeque::new();
749             let mut add_child = |bfs_queue: &mut VecDeque<_>, child: ChildItem, parent: DefId| {
750                 let child = match child.def {
751                     DefLike::DlDef(def) if child.vis == ty::Visibility::Public => def.def_id(),
752                     _ => return,
753                 };
754
755                 match visible_parent_map.entry(child) {
756                     Entry::Occupied(mut entry) => {
757                         // If `child` is defined in crate `cnum`, ensure
758                         // that it is mapped to a parent in `cnum`.
759                         if child.krate == cnum && entry.get().krate != cnum {
760                             entry.insert(parent);
761                         }
762                     }
763                     Entry::Vacant(entry) => {
764                         entry.insert(parent);
765                         bfs_queue.push_back(child);
766                     }
767                 }
768             };
769
770             let croot = DefId { krate: cnum, index: CRATE_DEF_INDEX };
771             for child in self.crate_top_level_items(cnum) {
772                 add_child(bfs_queue, child, croot);
773             }
774             while let Some(def) = bfs_queue.pop_front() {
775                 for child in self.item_children(def) {
776                     add_child(bfs_queue, child, def);
777                 }
778             }
779         }
780
781         visible_parent_map
782     }
783 }
784