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