1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
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.
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.
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.
25 use hir::def::{self, Def};
26 use hir::def_id::{DefId, DefIndex};
27 use hir::map as hir_map;
28 use hir::map::definitions::DefKey;
30 use middle::lang_items;
31 use ty::{self, Ty, TyCtxt, VariantKind};
33 use mir::mir_map::MirMap;
35 use session::config::PanicStrategy;
36 use session::search_paths::PathKind;
37 use util::nodemap::{FnvHashMap, NodeSet, DefIdMap};
39 use std::path::PathBuf;
43 use syntax::parse::token::InternedString;
45 use rustc_back::target::Target;
47 use hir::intravisit::Visitor;
49 pub use self::DefLike::{DlDef, DlField, DlImpl};
50 pub use self::NativeLibraryKind::{NativeStatic, NativeFramework, NativeUnknown};
52 // lonely orphan structs and enums looking for a better home
54 #[derive(Clone, Debug)]
56 pub crate_name: String,
60 // Where a crate came from on the local filesystem. One of these two options
62 #[derive(PartialEq, Clone, Debug)]
63 pub struct CrateSource {
64 pub dylib: Option<(PathBuf, PathKind)>,
65 pub rlib: Option<(PathBuf, PathKind)>,
66 pub cnum: ast::CrateNum,
69 #[derive(Copy, Debug, PartialEq, Clone)]
70 pub enum LinkagePreference {
76 #[derive(Copy, Clone, PartialEq)]
77 pub enum NativeLibraryKind {
78 NativeStatic, // native static library (.a archive)
79 NativeFramework, // OSX-specific
80 NativeUnknown, // default way to specify a dynamic library
84 // Something that a name can resolve to.
85 #[derive(Copy, Clone, Debug)]
92 /// The data we save and restore about an inlined item or method. This is not
93 /// part of the AST that we parse from a file, but it becomes part of the tree
95 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
96 pub enum InlinedItem {
97 Item(DefId /* def-id in source crate */, P<hir::Item>),
98 TraitItem(DefId /* impl id */, P<hir::TraitItem>),
99 ImplItem(DefId /* impl id */, P<hir::ImplItem>),
100 Foreign(DefId /* extern item */, P<hir::ForeignItem>),
103 /// A borrowed version of `hir::InlinedItem`.
104 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
105 pub enum InlinedItemRef<'a> {
106 Item(DefId, &'a hir::Item),
107 TraitItem(DefId, &'a hir::TraitItem),
108 ImplItem(DefId, &'a hir::ImplItem),
109 Foreign(DefId, &'a hir::ForeignItem)
112 /// Item definitions in the currently-compiled crate would have the CrateNum
113 /// LOCAL_CRATE in their DefId.
114 pub const LOCAL_CRATE: ast::CrateNum = 0;
116 #[derive(Copy, Clone)]
117 pub struct ChildItem {
120 pub vis: ty::Visibility,
123 #[derive(Copy, Clone, Debug)]
124 pub struct ExternCrate {
125 /// def_id of an `extern crate` in the current crate that caused
126 /// this crate to be loaded; note that there could be multiple
130 /// span of the extern crate that caused this to be loaded
133 /// If true, then this crate is the crate named by the extern
134 /// crate referenced above. If false, then this crate is a dep
138 /// Number of links to reach the extern crate `def_id`
139 /// declaration; used to select the extern crate with the shortest
144 /// A store of Rust crates, through with their metadata
146 pub trait CrateStore<'tcx> {
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) -> ty::ItemVariances;
155 fn repr_attrs(&self, def: DefId) -> Vec<attr::ReprAttr>;
156 fn item_type<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
157 -> ty::TypeScheme<'tcx>;
158 fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>>;
159 fn item_name(&self, def: DefId) -> ast::Name;
160 fn opt_item_name(&self, def: DefId) -> Option<ast::Name>;
161 fn item_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
162 -> ty::GenericPredicates<'tcx>;
163 fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
164 -> ty::GenericPredicates<'tcx>;
165 fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>;
166 fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef<'tcx>;
167 fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>;
168 fn method_arg_names(&self, did: DefId) -> Vec<String>;
169 fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId>;
172 fn implementations_of_trait(&self, def_id: DefId) -> Vec<DefId>;
173 fn provided_trait_methods<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
174 -> Vec<Rc<ty::Method<'tcx>>>;
175 fn trait_item_def_ids(&self, def: DefId)
176 -> Vec<ty::ImplOrTraitItemId>;
179 fn impl_items(&self, impl_def_id: DefId) -> Vec<ty::ImplOrTraitItemId>;
180 fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
181 -> Option<ty::TraitRef<'tcx>>;
182 fn impl_polarity(&self, def: DefId) -> Option<hir::ImplPolarity>;
183 fn custom_coerce_unsized_kind(&self, def: DefId)
184 -> Option<ty::adjustment::CustomCoerceUnsized>;
185 fn associated_consts<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
186 -> Vec<Rc<ty::AssociatedConst<'tcx>>>;
187 fn impl_parent(&self, impl_def_id: DefId) -> Option<DefId>;
189 // trait/impl-item info
190 fn trait_of_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
192 fn impl_or_trait_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
193 -> Option<ty::ImplOrTraitItem<'tcx>>;
196 fn is_const_fn(&self, did: DefId) -> bool;
197 fn is_defaulted_trait(&self, did: DefId) -> bool;
198 fn is_impl(&self, did: DefId) -> bool;
199 fn is_default_impl(&self, impl_did: DefId) -> bool;
200 fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool;
201 fn is_foreign_item(&self, did: DefId) -> bool;
202 fn is_static_method(&self, did: DefId) -> bool;
203 fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool;
204 fn is_typedef(&self, did: DefId) -> bool;
207 fn dylib_dependency_formats(&self, cnum: ast::CrateNum)
208 -> Vec<(ast::CrateNum, LinkagePreference)>;
209 fn lang_items(&self, cnum: ast::CrateNum) -> Vec<(DefIndex, usize)>;
210 fn missing_lang_items(&self, cnum: ast::CrateNum) -> Vec<lang_items::LangItem>;
211 fn is_staged_api(&self, cnum: ast::CrateNum) -> bool;
212 fn is_explicitly_linked(&self, cnum: ast::CrateNum) -> bool;
213 fn is_allocator(&self, cnum: ast::CrateNum) -> bool;
214 fn is_panic_runtime(&self, cnum: ast::CrateNum) -> bool;
215 fn panic_strategy(&self, cnum: ast::CrateNum) -> PanicStrategy;
216 fn extern_crate(&self, cnum: ast::CrateNum) -> Option<ExternCrate>;
217 fn crate_attrs(&self, cnum: ast::CrateNum) -> Vec<ast::Attribute>;
218 /// The name of the crate as it is referred to in source code of the current
220 fn crate_name(&self, cnum: ast::CrateNum) -> InternedString;
221 /// The name of the crate as it is stored in the crate's metadata.
222 fn original_crate_name(&self, cnum: ast::CrateNum) -> InternedString;
223 fn crate_hash(&self, cnum: ast::CrateNum) -> Svh;
224 fn crate_disambiguator(&self, cnum: ast::CrateNum) -> InternedString;
225 fn crate_struct_field_attrs(&self, cnum: ast::CrateNum)
226 -> FnvHashMap<DefId, Vec<ast::Attribute>>;
227 fn plugin_registrar_fn(&self, cnum: ast::CrateNum) -> Option<DefId>;
228 fn native_libraries(&self, cnum: ast::CrateNum) -> Vec<(NativeLibraryKind, String)>;
229 fn reachable_ids(&self, cnum: ast::CrateNum) -> Vec<DefId>;
232 fn def_index_for_def_key(&self,
236 fn def_key(&self, def: DefId) -> hir_map::DefKey;
237 fn relative_def_path(&self, def: DefId) -> hir_map::DefPath;
238 fn variant_kind(&self, def_id: DefId) -> Option<VariantKind>;
239 fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option<DefId>;
240 fn tuple_struct_definition_if_ctor(&self, did: DefId) -> Option<DefId>;
241 fn struct_field_names(&self, def: DefId) -> Vec<ast::Name>;
242 fn item_children(&self, did: DefId) -> Vec<ChildItem>;
243 fn crate_top_level_items(&self, cnum: ast::CrateNum) -> Vec<ChildItem>;
246 fn maybe_get_item_ast<'a>(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
247 -> Option<(&'tcx InlinedItem, ast::NodeId)>;
248 fn local_node_for_inlined_defid(&'tcx self, def_id: DefId) -> Option<ast::NodeId>;
249 fn defid_for_inlined_node(&'tcx self, node_id: ast::NodeId) -> Option<DefId>;
251 fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
252 -> Option<Mir<'tcx>>;
253 fn is_item_mir_available(&self, def: DefId) -> bool;
255 // This is basically a 1-based range of ints, which is a little
256 // silly - I may fix that.
257 fn crates(&self) -> Vec<ast::CrateNum>;
258 fn used_libraries(&self) -> Vec<(String, NativeLibraryKind)>;
259 fn used_link_args(&self) -> Vec<String>;
262 fn metadata_filename(&self) -> &str;
263 fn metadata_section_name(&self, target: &Target) -> &str;
264 fn encode_type<'a>(&self,
265 tcx: TyCtxt<'a, 'tcx, 'tcx>,
267 def_id_to_string: for<'b> fn(TyCtxt<'b, 'tcx, 'tcx>, DefId) -> String)
269 fn used_crates(&self, prefer: LinkagePreference) -> Vec<(ast::CrateNum, Option<PathBuf>)>;
270 fn used_crate_source(&self, cnum: ast::CrateNum) -> CrateSource;
271 fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<ast::CrateNum>;
272 fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
273 reexports: &def::ExportMap,
274 link_meta: &LinkMeta,
276 mir_map: &MirMap<'tcx>,
277 krate: &hir::Crate) -> Vec<u8>;
278 fn metadata_encoding_version(&self) -> &[u8];
282 pub fn visit<'ast,V>(&'ast self, visitor: &mut V)
283 where V: Visitor<'ast>
286 InlinedItem::Item(_, ref i) => visitor.visit_item(&i),
287 InlinedItem::Foreign(_, ref i) => visitor.visit_foreign_item(&i),
288 InlinedItem::TraitItem(_, ref ti) => visitor.visit_trait_item(ti),
289 InlinedItem::ImplItem(_, ref ii) => visitor.visit_impl_item(ii),
294 // FIXME: find a better place for this?
295 pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
296 let mut err_count = 0;
298 let mut say = |s: &str| {
300 (_, None) => bug!("{}", s),
301 (Some(sp), Some(sess)) => sess.span_err(sp, s),
302 (None, Some(sess)) => sess.err(s),
307 say("crate name must not be empty");
310 if c.is_alphanumeric() { continue }
311 if c == '_' { continue }
312 say(&format!("invalid character `{}` in crate name: `{}`", c, s));
317 sess.unwrap().abort_if_errors();
321 /// A dummy crate store that does not support any non-local crates,
322 /// for test purposes.
323 pub struct DummyCrateStore;
324 #[allow(unused_variables)]
325 impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
327 fn stability(&self, def: DefId) -> Option<attr::Stability> { bug!("stability") }
328 fn deprecation(&self, def: DefId) -> Option<attr::Deprecation> { bug!("deprecation") }
329 fn visibility(&self, def: DefId) -> ty::Visibility { bug!("visibility") }
330 fn closure_kind(&self, def_id: DefId) -> ty::ClosureKind { bug!("closure_kind") }
331 fn closure_ty<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
332 -> ty::ClosureTy<'tcx> { bug!("closure_ty") }
333 fn item_variances(&self, def: DefId) -> ty::ItemVariances { bug!("item_variances") }
334 fn repr_attrs(&self, def: DefId) -> Vec<attr::ReprAttr> { bug!("repr_attrs") }
335 fn item_type<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
336 -> ty::TypeScheme<'tcx> { bug!("item_type") }
337 fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>> {
338 bug!("visible_parent_map")
340 fn item_name(&self, def: DefId) -> ast::Name { bug!("item_name") }
341 fn opt_item_name(&self, def: DefId) -> Option<ast::Name> { bug!("opt_item_name") }
342 fn item_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
343 -> ty::GenericPredicates<'tcx> { bug!("item_predicates") }
344 fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
345 -> ty::GenericPredicates<'tcx> { bug!("item_super_predicates") }
346 fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute> { bug!("item_attrs") }
347 fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef<'tcx>
348 { bug!("trait_def") }
349 fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>
351 fn method_arg_names(&self, did: DefId) -> Vec<String> { bug!("method_arg_names") }
352 fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId> { vec![] }
355 fn implementations_of_trait(&self, def_id: DefId) -> Vec<DefId> { vec![] }
356 fn provided_trait_methods<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
357 -> Vec<Rc<ty::Method<'tcx>>> { bug!("provided_trait_methods") }
358 fn trait_item_def_ids(&self, def: DefId)
359 -> Vec<ty::ImplOrTraitItemId> { bug!("trait_item_def_ids") }
360 fn def_index_for_def_key(&self,
363 -> Option<DefIndex> {
368 fn impl_items(&self, impl_def_id: DefId) -> Vec<ty::ImplOrTraitItemId>
369 { bug!("impl_items") }
370 fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
371 -> Option<ty::TraitRef<'tcx>> { bug!("impl_trait_ref") }
372 fn impl_polarity(&self, def: DefId) -> Option<hir::ImplPolarity> { bug!("impl_polarity") }
373 fn custom_coerce_unsized_kind(&self, def: DefId)
374 -> Option<ty::adjustment::CustomCoerceUnsized>
375 { bug!("custom_coerce_unsized_kind") }
376 fn associated_consts<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
377 -> Vec<Rc<ty::AssociatedConst<'tcx>>> { bug!("associated_consts") }
378 fn impl_parent(&self, def: DefId) -> Option<DefId> { bug!("impl_parent") }
380 // trait/impl-item info
381 fn trait_of_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
382 -> Option<DefId> { bug!("trait_of_item") }
383 fn impl_or_trait_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
384 -> Option<ty::ImplOrTraitItem<'tcx>> { bug!("impl_or_trait_item") }
387 fn is_const_fn(&self, did: DefId) -> bool { bug!("is_const_fn") }
388 fn is_defaulted_trait(&self, did: DefId) -> bool { bug!("is_defaulted_trait") }
389 fn is_impl(&self, did: DefId) -> bool { bug!("is_impl") }
390 fn is_default_impl(&self, impl_did: DefId) -> bool { bug!("is_default_impl") }
391 fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool
392 { bug!("is_extern_item") }
393 fn is_foreign_item(&self, did: DefId) -> bool { bug!("is_foreign_item") }
394 fn is_static_method(&self, did: DefId) -> bool { bug!("is_static_method") }
395 fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool { false }
396 fn is_typedef(&self, did: DefId) -> bool { bug!("is_typedef") }
399 fn dylib_dependency_formats(&self, cnum: ast::CrateNum)
400 -> Vec<(ast::CrateNum, LinkagePreference)>
401 { bug!("dylib_dependency_formats") }
402 fn lang_items(&self, cnum: ast::CrateNum) -> Vec<(DefIndex, usize)>
403 { bug!("lang_items") }
404 fn missing_lang_items(&self, cnum: ast::CrateNum) -> Vec<lang_items::LangItem>
405 { bug!("missing_lang_items") }
406 fn is_staged_api(&self, cnum: ast::CrateNum) -> bool { bug!("is_staged_api") }
407 fn is_explicitly_linked(&self, cnum: ast::CrateNum) -> bool { bug!("is_explicitly_linked") }
408 fn is_allocator(&self, cnum: ast::CrateNum) -> bool { bug!("is_allocator") }
409 fn is_panic_runtime(&self, cnum: ast::CrateNum) -> bool { bug!("is_panic_runtime") }
410 fn panic_strategy(&self, cnum: ast::CrateNum) -> PanicStrategy {
411 bug!("panic_strategy")
413 fn extern_crate(&self, cnum: ast::CrateNum) -> Option<ExternCrate> { bug!("extern_crate") }
414 fn crate_attrs(&self, cnum: ast::CrateNum) -> Vec<ast::Attribute>
415 { bug!("crate_attrs") }
416 fn crate_name(&self, cnum: ast::CrateNum) -> InternedString { bug!("crate_name") }
417 fn original_crate_name(&self, cnum: ast::CrateNum) -> InternedString {
418 bug!("original_crate_name")
420 fn crate_hash(&self, cnum: ast::CrateNum) -> Svh { bug!("crate_hash") }
421 fn crate_disambiguator(&self, cnum: ast::CrateNum)
422 -> InternedString { bug!("crate_disambiguator") }
423 fn crate_struct_field_attrs(&self, cnum: ast::CrateNum)
424 -> FnvHashMap<DefId, Vec<ast::Attribute>>
425 { bug!("crate_struct_field_attrs") }
426 fn plugin_registrar_fn(&self, cnum: ast::CrateNum) -> Option<DefId>
427 { bug!("plugin_registrar_fn") }
428 fn native_libraries(&self, cnum: ast::CrateNum) -> Vec<(NativeLibraryKind, String)>
429 { bug!("native_libraries") }
430 fn reachable_ids(&self, cnum: ast::CrateNum) -> Vec<DefId> { bug!("reachable_ids") }
433 fn def_key(&self, def: DefId) -> hir_map::DefKey { bug!("def_key") }
434 fn relative_def_path(&self, def: DefId) -> hir_map::DefPath { bug!("relative_def_path") }
435 fn variant_kind(&self, def_id: DefId) -> Option<VariantKind> { bug!("variant_kind") }
436 fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option<DefId>
437 { bug!("struct_ctor_def_id") }
438 fn tuple_struct_definition_if_ctor(&self, did: DefId) -> Option<DefId>
439 { bug!("tuple_struct_definition_if_ctor") }
440 fn struct_field_names(&self, def: DefId) -> Vec<ast::Name> { bug!("struct_field_names") }
441 fn item_children(&self, did: DefId) -> Vec<ChildItem> { bug!("item_children") }
442 fn crate_top_level_items(&self, cnum: ast::CrateNum) -> Vec<ChildItem>
443 { bug!("crate_top_level_items") }
446 fn maybe_get_item_ast<'a>(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
447 -> Option<(&'tcx InlinedItem, ast::NodeId)> {
448 bug!("maybe_get_item_ast")
450 fn local_node_for_inlined_defid(&'tcx self, def_id: DefId) -> Option<ast::NodeId> {
451 bug!("local_node_for_inlined_defid")
453 fn defid_for_inlined_node(&'tcx self, node_id: ast::NodeId) -> Option<DefId> {
454 bug!("defid_for_inlined_node")
457 fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
458 -> Option<Mir<'tcx>> { bug!("maybe_get_item_mir") }
459 fn is_item_mir_available(&self, def: DefId) -> bool {
460 bug!("is_item_mir_available")
463 // This is basically a 1-based range of ints, which is a little
464 // silly - I may fix that.
465 fn crates(&self) -> Vec<ast::CrateNum> { vec![] }
466 fn used_libraries(&self) -> Vec<(String, NativeLibraryKind)> { vec![] }
467 fn used_link_args(&self) -> Vec<String> { vec![] }
470 fn metadata_filename(&self) -> &str { bug!("metadata_filename") }
471 fn metadata_section_name(&self, target: &Target) -> &str { bug!("metadata_section_name") }
472 fn encode_type<'a>(&self,
473 tcx: TyCtxt<'a, 'tcx, 'tcx>,
475 def_id_to_string: for<'b> fn(TyCtxt<'b, 'tcx, 'tcx>, DefId) -> String)
479 fn used_crates(&self, prefer: LinkagePreference) -> Vec<(ast::CrateNum, Option<PathBuf>)>
481 fn used_crate_source(&self, cnum: ast::CrateNum) -> CrateSource { bug!("used_crate_source") }
482 fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<ast::CrateNum> { None }
483 fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
484 reexports: &def::ExportMap,
485 link_meta: &LinkMeta,
487 mir_map: &MirMap<'tcx>,
488 krate: &hir::Crate) -> Vec<u8> { vec![] }
489 fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") }
493 /// Metadata encoding and decoding can make use of thread-local encoding and
494 /// decoding contexts. These allow implementers of serialize::Encodable and
495 /// Decodable to access information and datastructures that would otherwise not
496 /// be available to them. For example, we can automatically translate def-id and
497 /// span information during decoding because the decoding context knows which
498 /// crate the data is decoded from. Or it allows to make ty::Ty decodable
499 /// because the context has access to the TyCtxt that is needed for creating
500 /// ty::Ty instances.
502 /// Note, however, that this only works for RBML-based encoding and decoding at
505 use rbml::opaque::Encoder as OpaqueEncoder;
506 use rbml::opaque::Decoder as OpaqueDecoder;
510 use ty::{self, Ty, TyCtxt};
511 use ty::subst::Substs;
512 use hir::def_id::DefId;
514 pub trait EncodingContext<'tcx> {
515 fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx>;
516 fn encode_ty(&self, encoder: &mut OpaqueEncoder, t: Ty<'tcx>);
517 fn encode_substs(&self, encoder: &mut OpaqueEncoder, substs: &Substs<'tcx>);
520 /// Marker type used for the TLS slot.
521 /// The type context cannot be used directly because the TLS
522 /// in libstd doesn't allow types generic over lifetimes.
526 static TLS_ENCODING: Cell<Option<*const TlsPayload>> = Cell::new(None)
529 /// Execute f after pushing the given EncodingContext onto the TLS stack.
530 pub fn enter_encoding_context<'tcx, F, R>(ecx: &EncodingContext<'tcx>,
531 encoder: &mut OpaqueEncoder,
533 where F: FnOnce(&EncodingContext<'tcx>, &mut OpaqueEncoder) -> R
535 let tls_payload = (ecx as *const _, encoder as *mut _);
536 let tls_ptr = &tls_payload as *const _ as *const TlsPayload;
537 TLS_ENCODING.with(|tls| {
538 let prev = tls.get();
539 tls.set(Some(tls_ptr));
540 let ret = f(ecx, encoder);
546 /// Execute f with access to the thread-local encoding context and
547 /// rbml encoder. This function will panic if the encoder passed in and the
548 /// context encoder are not the same.
550 /// Note that this method is 'practically' safe due to its checking that the
551 /// encoder passed in is the same as the one in TLS, but it would still be
552 /// possible to construct cases where the EncodingContext is exchanged
553 /// while the same encoder is used, thus working with a wrong context.
554 pub fn with_encoding_context<'tcx, E, F, R>(encoder: &mut E, f: F) -> R
555 where F: FnOnce(&EncodingContext<'tcx>, &mut OpaqueEncoder) -> R,
556 E: serialize::Encoder
559 unsafe_with_encoding_context(|ecx, tls_encoder| {
560 assert!(encoder as *mut _ as usize == tls_encoder as *mut _ as usize);
562 let ecx: &EncodingContext<'tcx> = mem::transmute(ecx);
569 /// Execute f with access to the thread-local encoding context and
571 pub unsafe fn unsafe_with_encoding_context<F, R>(f: F) -> R
572 where F: FnOnce(&EncodingContext, &mut OpaqueEncoder) -> R
574 TLS_ENCODING.with(|tls| {
575 let tls = tls.get().unwrap();
576 let tls_payload = tls as *mut (&EncodingContext, &mut OpaqueEncoder);
577 f((*tls_payload).0, (*tls_payload).1)
581 pub trait DecodingContext<'tcx> {
582 fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx>;
583 fn decode_ty(&self, decoder: &mut OpaqueDecoder) -> ty::Ty<'tcx>;
584 fn decode_substs(&self, decoder: &mut OpaqueDecoder) -> Substs<'tcx>;
585 fn translate_def_id(&self, def_id: DefId) -> DefId;
589 static TLS_DECODING: Cell<Option<*const TlsPayload>> = Cell::new(None)
592 /// Execute f after pushing the given DecodingContext onto the TLS stack.
593 pub fn enter_decoding_context<'tcx, F, R>(dcx: &DecodingContext<'tcx>,
594 decoder: &mut OpaqueDecoder,
596 where F: FnOnce(&DecodingContext<'tcx>, &mut OpaqueDecoder) -> R
598 let tls_payload = (dcx as *const _, decoder as *mut _);
599 let tls_ptr = &tls_payload as *const _ as *const TlsPayload;
600 TLS_DECODING.with(|tls| {
601 let prev = tls.get();
602 tls.set(Some(tls_ptr));
603 let ret = f(dcx, decoder);
609 /// Execute f with access to the thread-local decoding context and
610 /// rbml decoder. This function will panic if the decoder passed in and the
611 /// context decoder are not the same.
613 /// Note that this method is 'practically' safe due to its checking that the
614 /// decoder passed in is the same as the one in TLS, but it would still be
615 /// possible to construct cases where the DecodingContext is exchanged
616 /// while the same decoder is used, thus working with a wrong context.
617 pub fn with_decoding_context<'decoder, 'tcx, D, F, R>(d: &'decoder mut D, f: F) -> R
618 where D: serialize::Decoder,
619 F: FnOnce(&DecodingContext<'tcx>,
620 &mut OpaqueDecoder) -> R,
624 unsafe_with_decoding_context(|dcx, decoder| {
625 assert!((d as *mut _ as usize) == (decoder as *mut _ as usize));
627 let dcx: &DecodingContext<'tcx> = mem::transmute(dcx);
634 /// Execute f with access to the thread-local decoding context and
636 pub unsafe fn unsafe_with_decoding_context<F, R>(f: F) -> R
637 where F: FnOnce(&DecodingContext, &mut OpaqueDecoder) -> R
639 TLS_DECODING.with(|tls| {
640 let tls = tls.get().unwrap();
641 let tls_payload = tls as *mut (&DecodingContext, &mut OpaqueDecoder);
642 f((*tls_payload).0, (*tls_payload).1)