]> git.lizzy.rs Git - rust.git/blob - src/librustc/middle/cstore.rs
f61978271e7f6c34e1bb095e9e8dca16c0c23ffb
[rust.git] / src / librustc / middle / cstore.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 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
12 // file at the top-level directory of this distribution and at
13 // http://rust-lang.org/COPYRIGHT.
14 //
15 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
16 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
17 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
18 // option. This file may not be copied, modified, or distributed
19 // except according to those terms.
20
21 // the rustc crate store interface. This also includes types that
22 // are *mostly* used as a part of that interface, but these should
23 // probably get a better home if someone can find one.
24
25 use hir::def::{self, Def};
26 use hir::def_id::{CrateNum, DefId, DefIndex};
27 use hir::map as hir_map;
28 use hir::map::definitions::{Definitions, DefKey};
29 use hir::svh::Svh;
30 use middle::lang_items;
31 use ty::{self, Ty, TyCtxt};
32 use mir::Mir;
33 use session::Session;
34 use session::search_paths::PathKind;
35 use util::nodemap::{NodeSet, DefIdMap};
36 use std::path::PathBuf;
37 use std::rc::Rc;
38 use syntax::ast;
39 use syntax::attr;
40 use syntax::ext::base::SyntaxExtension;
41 use syntax::ptr::P;
42 use syntax::parse::token::InternedString;
43 use syntax_pos::Span;
44 use rustc_back::target::Target;
45 use hir;
46 use hir::intravisit::Visitor;
47 use rustc_back::PanicStrategy;
48
49 pub use self::NativeLibraryKind::{NativeStatic, NativeFramework, NativeUnknown};
50
51 // lonely orphan structs and enums looking for a better home
52
53 #[derive(Clone, Debug)]
54 pub struct LinkMeta {
55     pub crate_name: String,
56     pub crate_hash: Svh,
57 }
58
59 // Where a crate came from on the local filesystem. One of these two options
60 // must be non-None.
61 #[derive(PartialEq, Clone, Debug)]
62 pub struct CrateSource {
63     pub dylib: Option<(PathBuf, PathKind)>,
64     pub rlib: Option<(PathBuf, PathKind)>,
65 }
66
67 #[derive(RustcEncodable, RustcDecodable, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)]
68 pub enum DepKind {
69     /// A dependency that is only used for its macros.
70     MacrosOnly,
71     /// A dependency that is always injected into the dependency list and so
72     /// doesn't need to be linked to an rlib, e.g. the injected allocator.
73     Implicit,
74     /// A dependency that is required by an rlib version of this crate.
75     /// Ordinary `extern crate`s result in `Explicit` dependencies.
76     Explicit,
77 }
78
79 #[derive(Copy, Debug, PartialEq, Clone, RustcEncodable, RustcDecodable)]
80 pub enum LinkagePreference {
81     RequireDynamic,
82     RequireStatic,
83 }
84
85 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
86 pub enum NativeLibraryKind {
87     NativeStatic,    // native static library (.a archive)
88     NativeFramework, // OSX-specific
89     NativeUnknown,   // default way to specify a dynamic library
90 }
91
92 #[derive(Clone, Hash, RustcEncodable, RustcDecodable)]
93 pub struct NativeLibrary {
94     pub kind: NativeLibraryKind,
95     pub name: String,
96     pub cfg: Option<P<ast::MetaItem>>,
97 }
98
99 /// The data we save and restore about an inlined item or method.  This is not
100 /// part of the AST that we parse from a file, but it becomes part of the tree
101 /// that we trans.
102 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
103 pub enum InlinedItem {
104     Item(DefId /* def-id in source crate */, P<hir::Item>),
105     TraitItem(DefId /* impl id */, P<hir::TraitItem>),
106     ImplItem(DefId /* impl id */, P<hir::ImplItem>)
107 }
108
109 /// A borrowed version of `hir::InlinedItem`.
110 #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, Hash, Debug)]
111 pub enum InlinedItemRef<'a> {
112     Item(DefId, &'a hir::Item),
113     TraitItem(DefId, &'a hir::TraitItem),
114     ImplItem(DefId, &'a hir::ImplItem)
115 }
116
117 pub enum LoadedMacro {
118     MacroRules(ast::MacroDef),
119     ProcMacro(Rc<SyntaxExtension>),
120 }
121
122 #[derive(Copy, Clone, Debug)]
123 pub struct ExternCrate {
124     /// def_id of an `extern crate` in the current crate that caused
125     /// this crate to be loaded; note that there could be multiple
126     /// such ids
127     pub def_id: DefId,
128
129     /// span of the extern crate that caused this to be loaded
130     pub span: Span,
131
132     /// If true, then this crate is the crate named by the extern
133     /// crate referenced above. If false, then this crate is a dep
134     /// of the crate.
135     pub direct: bool,
136
137     /// Number of links to reach the extern crate `def_id`
138     /// declaration; used to select the extern crate with the shortest
139     /// path
140     pub path_len: usize,
141 }
142
143 /// A store of Rust crates, through with their metadata
144 /// can be accessed.
145 pub trait CrateStore<'tcx> {
146     // item info
147     fn describe_def(&self, def: DefId) -> Option<Def>;
148     fn stability(&self, def: DefId) -> Option<attr::Stability>;
149     fn deprecation(&self, def: DefId) -> Option<attr::Deprecation>;
150     fn visibility(&self, def: DefId) -> ty::Visibility;
151     fn closure_kind(&self, def_id: DefId) -> ty::ClosureKind;
152     fn closure_ty<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
153                       -> ty::ClosureTy<'tcx>;
154     fn item_variances(&self, def: DefId) -> Vec<ty::Variance>;
155     fn item_type<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
156                      -> Ty<'tcx>;
157     fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>>;
158     fn item_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
159                            -> ty::GenericPredicates<'tcx>;
160     fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
161                                  -> ty::GenericPredicates<'tcx>;
162     fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
163                          -> ty::Generics<'tcx>;
164     fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>;
165     fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef<'tcx>;
166     fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>;
167     fn fn_arg_names(&self, did: DefId) -> Vec<ast::Name>;
168     fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId>;
169
170     // trait info
171     fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId>;
172
173     // impl info
174     fn associated_item_def_ids(&self, def_id: DefId) -> Vec<DefId>;
175     fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
176                           -> Option<ty::TraitRef<'tcx>>;
177     fn impl_polarity(&self, def: DefId) -> hir::ImplPolarity;
178     fn custom_coerce_unsized_kind(&self, def: DefId)
179                                   -> Option<ty::adjustment::CustomCoerceUnsized>;
180     fn impl_parent(&self, impl_def_id: DefId) -> Option<DefId>;
181
182     // trait/impl-item info
183     fn trait_of_item(&self, def_id: DefId) -> Option<DefId>;
184     fn associated_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
185                            -> Option<ty::AssociatedItem>;
186
187     // flags
188     fn is_const_fn(&self, did: DefId) -> bool;
189     fn is_defaulted_trait(&self, did: DefId) -> bool;
190     fn is_default_impl(&self, impl_did: DefId) -> bool;
191     fn is_foreign_item(&self, did: DefId) -> bool;
192     fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool;
193
194     // crate metadata
195     fn dylib_dependency_formats(&self, cnum: CrateNum)
196                                     -> Vec<(CrateNum, LinkagePreference)>;
197     fn dep_kind(&self, cnum: CrateNum) -> DepKind;
198     fn lang_items(&self, cnum: CrateNum) -> Vec<(DefIndex, usize)>;
199     fn missing_lang_items(&self, cnum: CrateNum) -> Vec<lang_items::LangItem>;
200     fn is_staged_api(&self, cnum: CrateNum) -> bool;
201     fn is_allocator(&self, cnum: CrateNum) -> bool;
202     fn is_panic_runtime(&self, cnum: CrateNum) -> bool;
203     fn is_compiler_builtins(&self, cnum: CrateNum) -> bool;
204     fn panic_strategy(&self, cnum: CrateNum) -> PanicStrategy;
205     fn extern_crate(&self, cnum: CrateNum) -> Option<ExternCrate>;
206     /// The name of the crate as it is referred to in source code of the current
207     /// crate.
208     fn crate_name(&self, cnum: CrateNum) -> InternedString;
209     /// The name of the crate as it is stored in the crate's metadata.
210     fn original_crate_name(&self, cnum: CrateNum) -> InternedString;
211     fn crate_hash(&self, cnum: CrateNum) -> Svh;
212     fn crate_disambiguator(&self, cnum: CrateNum) -> InternedString;
213     fn plugin_registrar_fn(&self, cnum: CrateNum) -> Option<DefId>;
214     fn native_libraries(&self, cnum: CrateNum) -> Vec<NativeLibrary>;
215     fn reachable_ids(&self, cnum: CrateNum) -> Vec<DefId>;
216     fn is_no_builtins(&self, cnum: CrateNum) -> bool;
217
218     // resolve
219     fn def_index_for_def_key(&self,
220                              cnum: CrateNum,
221                              def: DefKey)
222                              -> Option<DefIndex>;
223     fn def_key(&self, def: DefId) -> hir_map::DefKey;
224     fn relative_def_path(&self, def: DefId) -> Option<hir_map::DefPath>;
225     fn struct_field_names(&self, def: DefId) -> Vec<ast::Name>;
226     fn item_children(&self, did: DefId) -> Vec<def::Export>;
227     fn load_macro(&self, did: DefId, sess: &Session) -> LoadedMacro;
228
229     // misc. metadata
230     fn maybe_get_item_ast<'a>(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
231                               -> Option<(&'tcx InlinedItem, ast::NodeId)>;
232     fn local_node_for_inlined_defid(&'tcx self, def_id: DefId) -> Option<ast::NodeId>;
233     fn defid_for_inlined_node(&'tcx self, node_id: ast::NodeId) -> Option<DefId>;
234
235     fn get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Mir<'tcx>;
236     fn is_item_mir_available(&self, def: DefId) -> bool;
237
238     // This is basically a 1-based range of ints, which is a little
239     // silly - I may fix that.
240     fn crates(&self) -> Vec<CrateNum>;
241     fn used_libraries(&self) -> Vec<NativeLibrary>;
242     fn used_link_args(&self) -> Vec<String>;
243
244     // utility functions
245     fn metadata_filename(&self) -> &str;
246     fn metadata_section_name(&self, target: &Target) -> &str;
247     fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, Option<PathBuf>)>;
248     fn used_crate_source(&self, cnum: CrateNum) -> CrateSource;
249     fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum>;
250     fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
251                            reexports: &def::ExportMap,
252                            link_meta: &LinkMeta,
253                            reachable: &NodeSet) -> Vec<u8>;
254     fn metadata_encoding_version(&self) -> &[u8];
255 }
256
257 impl InlinedItem {
258     pub fn visit<'ast,V>(&'ast self, visitor: &mut V)
259         where V: Visitor<'ast>
260     {
261         match *self {
262             InlinedItem::Item(_, ref i) => visitor.visit_item(&i),
263             InlinedItem::TraitItem(_, ref ti) => visitor.visit_trait_item(ti),
264             InlinedItem::ImplItem(_, ref ii) => visitor.visit_impl_item(ii),
265         }
266     }
267 }
268
269 // FIXME: find a better place for this?
270 pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
271     let mut err_count = 0;
272     {
273         let mut say = |s: &str| {
274             match (sp, sess) {
275                 (_, None) => bug!("{}", s),
276                 (Some(sp), Some(sess)) => sess.span_err(sp, s),
277                 (None, Some(sess)) => sess.err(s),
278             }
279             err_count += 1;
280         };
281         if s.is_empty() {
282             say("crate name must not be empty");
283         }
284         for c in s.chars() {
285             if c.is_alphanumeric() { continue }
286             if c == '_'  { continue }
287             say(&format!("invalid character `{}` in crate name: `{}`", c, s));
288         }
289     }
290
291     if err_count > 0 {
292         sess.unwrap().abort_if_errors();
293     }
294 }
295
296 /// A dummy crate store that does not support any non-local crates,
297 /// for test purposes.
298 pub struct DummyCrateStore;
299 #[allow(unused_variables)]
300 impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
301     // item info
302     fn describe_def(&self, def: DefId) -> Option<Def> { bug!("describe_def") }
303     fn stability(&self, def: DefId) -> Option<attr::Stability> { bug!("stability") }
304     fn deprecation(&self, def: DefId) -> Option<attr::Deprecation> { bug!("deprecation") }
305     fn visibility(&self, def: DefId) -> ty::Visibility { bug!("visibility") }
306     fn closure_kind(&self, def_id: DefId) -> ty::ClosureKind { bug!("closure_kind") }
307     fn closure_ty<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
308                       -> ty::ClosureTy<'tcx>  { bug!("closure_ty") }
309     fn item_variances(&self, def: DefId) -> Vec<ty::Variance> { bug!("item_variances") }
310     fn item_type<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
311                      -> Ty<'tcx> { bug!("item_type") }
312     fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>> {
313         bug!("visible_parent_map")
314     }
315     fn item_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
316                            -> ty::GenericPredicates<'tcx> { bug!("item_predicates") }
317     fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
318                                  -> ty::GenericPredicates<'tcx> { bug!("item_super_predicates") }
319     fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
320                          -> ty::Generics<'tcx> { bug!("item_generics") }
321     fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute> { bug!("item_attrs") }
322     fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef<'tcx>
323         { bug!("trait_def") }
324     fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>
325         { bug!("adt_def") }
326     fn fn_arg_names(&self, did: DefId) -> Vec<ast::Name> { bug!("fn_arg_names") }
327     fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId> { vec![] }
328
329     // trait info
330     fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId> { vec![] }
331     fn def_index_for_def_key(&self,
332                              cnum: CrateNum,
333                              def: DefKey)
334                              -> Option<DefIndex> {
335         None
336     }
337
338     // impl info
339     fn associated_item_def_ids(&self, def_id: DefId) -> Vec<DefId>
340         { bug!("associated_items") }
341     fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
342                           -> Option<ty::TraitRef<'tcx>> { bug!("impl_trait_ref") }
343     fn impl_polarity(&self, def: DefId) -> hir::ImplPolarity { bug!("impl_polarity") }
344     fn custom_coerce_unsized_kind(&self, def: DefId)
345                                   -> Option<ty::adjustment::CustomCoerceUnsized>
346         { bug!("custom_coerce_unsized_kind") }
347     fn impl_parent(&self, def: DefId) -> Option<DefId> { bug!("impl_parent") }
348
349     // trait/impl-item info
350     fn trait_of_item(&self, def_id: DefId) -> Option<DefId> { bug!("trait_of_item") }
351     fn associated_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
352                            -> Option<ty::AssociatedItem> { bug!("associated_item") }
353
354     // flags
355     fn is_const_fn(&self, did: DefId) -> bool { bug!("is_const_fn") }
356     fn is_defaulted_trait(&self, did: DefId) -> bool { bug!("is_defaulted_trait") }
357     fn is_default_impl(&self, impl_did: DefId) -> bool { bug!("is_default_impl") }
358     fn is_foreign_item(&self, did: DefId) -> bool { bug!("is_foreign_item") }
359     fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool { false }
360
361     // crate metadata
362     fn dylib_dependency_formats(&self, cnum: CrateNum)
363                                     -> Vec<(CrateNum, LinkagePreference)>
364         { bug!("dylib_dependency_formats") }
365     fn lang_items(&self, cnum: CrateNum) -> Vec<(DefIndex, usize)>
366         { bug!("lang_items") }
367     fn missing_lang_items(&self, cnum: CrateNum) -> Vec<lang_items::LangItem>
368         { bug!("missing_lang_items") }
369     fn is_staged_api(&self, cnum: CrateNum) -> bool { bug!("is_staged_api") }
370     fn dep_kind(&self, cnum: CrateNum) -> DepKind { bug!("is_explicitly_linked") }
371     fn is_allocator(&self, cnum: CrateNum) -> bool { bug!("is_allocator") }
372     fn is_panic_runtime(&self, cnum: CrateNum) -> bool { bug!("is_panic_runtime") }
373     fn is_compiler_builtins(&self, cnum: CrateNum) -> bool { bug!("is_compiler_builtins") }
374     fn panic_strategy(&self, cnum: CrateNum) -> PanicStrategy {
375         bug!("panic_strategy")
376     }
377     fn extern_crate(&self, cnum: CrateNum) -> Option<ExternCrate> { bug!("extern_crate") }
378     fn crate_name(&self, cnum: CrateNum) -> InternedString { bug!("crate_name") }
379     fn original_crate_name(&self, cnum: CrateNum) -> InternedString {
380         bug!("original_crate_name")
381     }
382     fn crate_hash(&self, cnum: CrateNum) -> Svh { bug!("crate_hash") }
383     fn crate_disambiguator(&self, cnum: CrateNum)
384                            -> InternedString { bug!("crate_disambiguator") }
385     fn plugin_registrar_fn(&self, cnum: CrateNum) -> Option<DefId>
386         { bug!("plugin_registrar_fn") }
387     fn native_libraries(&self, cnum: CrateNum) -> Vec<NativeLibrary>
388         { bug!("native_libraries") }
389     fn reachable_ids(&self, cnum: CrateNum) -> Vec<DefId> { bug!("reachable_ids") }
390     fn is_no_builtins(&self, cnum: CrateNum) -> bool { bug!("is_no_builtins") }
391
392     // resolve
393     fn def_key(&self, def: DefId) -> hir_map::DefKey { bug!("def_key") }
394     fn relative_def_path(&self, def: DefId) -> Option<hir_map::DefPath> {
395         bug!("relative_def_path")
396     }
397     fn struct_field_names(&self, def: DefId) -> Vec<ast::Name> { bug!("struct_field_names") }
398     fn item_children(&self, did: DefId) -> Vec<def::Export> { bug!("item_children") }
399     fn load_macro(&self, did: DefId, sess: &Session) -> LoadedMacro { bug!("load_macro") }
400
401     // misc. metadata
402     fn maybe_get_item_ast<'a>(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
403                               -> Option<(&'tcx InlinedItem, ast::NodeId)> {
404         bug!("maybe_get_item_ast")
405     }
406     fn local_node_for_inlined_defid(&'tcx self, def_id: DefId) -> Option<ast::NodeId> {
407         bug!("local_node_for_inlined_defid")
408     }
409     fn defid_for_inlined_node(&'tcx self, node_id: ast::NodeId) -> Option<DefId> {
410         bug!("defid_for_inlined_node")
411     }
412
413     fn get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
414                         -> Mir<'tcx> { bug!("get_item_mir") }
415     fn is_item_mir_available(&self, def: DefId) -> bool {
416         bug!("is_item_mir_available")
417     }
418
419     // This is basically a 1-based range of ints, which is a little
420     // silly - I may fix that.
421     fn crates(&self) -> Vec<CrateNum> { vec![] }
422     fn used_libraries(&self) -> Vec<NativeLibrary> {
423         vec![]
424     }
425     fn used_link_args(&self) -> Vec<String> { vec![] }
426
427     // utility functions
428     fn metadata_filename(&self) -> &str { bug!("metadata_filename") }
429     fn metadata_section_name(&self, target: &Target) -> &str { bug!("metadata_section_name") }
430     fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, Option<PathBuf>)>
431         { vec![] }
432     fn used_crate_source(&self, cnum: CrateNum) -> CrateSource { bug!("used_crate_source") }
433     fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum> { None }
434     fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
435                            reexports: &def::ExportMap,
436                            link_meta: &LinkMeta,
437                            reachable: &NodeSet) -> Vec<u8> { vec![] }
438     fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") }
439 }
440
441 pub trait CrateLoader {
442     fn process_item(&mut self, item: &ast::Item, defs: &Definitions);
443     fn postprocess(&mut self, krate: &ast::Crate);
444 }