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, Eq, PartialOrd, Ord, Hash)]
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)
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_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
166 -> &'tcx ty::Generics<'tcx>;
167 fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>;
168 fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef<'tcx>;
169 fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>;
170 fn method_arg_names(&self, did: DefId) -> Vec<String>;
171 fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId>;
174 fn implementations_of_trait(&self, def_id: DefId) -> Vec<DefId>;
175 fn provided_trait_methods<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
176 -> Vec<Rc<ty::Method<'tcx>>>;
177 fn trait_item_def_ids(&self, def: DefId)
178 -> Vec<ty::ImplOrTraitItemId>;
181 fn impl_items(&self, impl_def_id: DefId) -> Vec<ty::ImplOrTraitItemId>;
182 fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
183 -> Option<ty::TraitRef<'tcx>>;
184 fn impl_polarity(&self, def: DefId) -> Option<hir::ImplPolarity>;
185 fn custom_coerce_unsized_kind(&self, def: DefId)
186 -> Option<ty::adjustment::CustomCoerceUnsized>;
187 fn associated_consts<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
188 -> Vec<Rc<ty::AssociatedConst<'tcx>>>;
189 fn impl_parent(&self, impl_def_id: DefId) -> Option<DefId>;
191 // trait/impl-item info
192 fn trait_of_item(&self, def_id: DefId) -> Option<DefId>;
193 fn impl_or_trait_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
194 -> Option<ty::ImplOrTraitItem<'tcx>>;
197 fn is_const_fn(&self, did: DefId) -> bool;
198 fn is_defaulted_trait(&self, did: DefId) -> bool;
199 fn is_impl(&self, did: DefId) -> bool;
200 fn is_default_impl(&self, impl_did: DefId) -> bool;
201 fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool;
202 fn is_foreign_item(&self, did: DefId) -> bool;
203 fn is_static_method(&self, did: DefId) -> bool;
204 fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool;
205 fn is_typedef(&self, did: DefId) -> bool;
208 fn dylib_dependency_formats(&self, cnum: ast::CrateNum)
209 -> Vec<(ast::CrateNum, LinkagePreference)>;
210 fn lang_items(&self, cnum: ast::CrateNum) -> Vec<(DefIndex, usize)>;
211 fn missing_lang_items(&self, cnum: ast::CrateNum) -> Vec<lang_items::LangItem>;
212 fn is_staged_api(&self, cnum: ast::CrateNum) -> bool;
213 fn is_explicitly_linked(&self, cnum: ast::CrateNum) -> bool;
214 fn is_allocator(&self, cnum: ast::CrateNum) -> bool;
215 fn is_panic_runtime(&self, cnum: ast::CrateNum) -> bool;
216 fn panic_strategy(&self, cnum: ast::CrateNum) -> PanicStrategy;
217 fn extern_crate(&self, cnum: ast::CrateNum) -> Option<ExternCrate>;
218 fn crate_attrs(&self, cnum: ast::CrateNum) -> Vec<ast::Attribute>;
219 /// The name of the crate as it is referred to in source code of the current
221 fn crate_name(&self, cnum: ast::CrateNum) -> InternedString;
222 /// The name of the crate as it is stored in the crate's metadata.
223 fn original_crate_name(&self, cnum: ast::CrateNum) -> InternedString;
224 fn crate_hash(&self, cnum: ast::CrateNum) -> Svh;
225 fn crate_disambiguator(&self, cnum: ast::CrateNum) -> InternedString;
226 fn crate_struct_field_attrs(&self, cnum: ast::CrateNum)
227 -> FnvHashMap<DefId, Vec<ast::Attribute>>;
228 fn plugin_registrar_fn(&self, cnum: ast::CrateNum) -> Option<DefId>;
229 fn native_libraries(&self, cnum: ast::CrateNum) -> Vec<(NativeLibraryKind, String)>;
230 fn reachable_ids(&self, cnum: ast::CrateNum) -> Vec<DefId>;
231 fn is_no_builtins(&self, cnum: ast::CrateNum) -> bool;
234 fn def_index_for_def_key(&self,
238 fn def_key(&self, def: DefId) -> hir_map::DefKey;
239 fn relative_def_path(&self, def: DefId) -> hir_map::DefPath;
240 fn variant_kind(&self, def_id: DefId) -> Option<VariantKind>;
241 fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option<DefId>;
242 fn tuple_struct_definition_if_ctor(&self, did: DefId) -> Option<DefId>;
243 fn struct_field_names(&self, def: DefId) -> Vec<ast::Name>;
244 fn item_children(&self, did: DefId) -> Vec<ChildItem>;
245 fn crate_top_level_items(&self, cnum: ast::CrateNum) -> Vec<ChildItem>;
248 fn maybe_get_item_ast<'a>(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
249 -> Option<(&'tcx InlinedItem, ast::NodeId)>;
250 fn local_node_for_inlined_defid(&'tcx self, def_id: DefId) -> Option<ast::NodeId>;
251 fn defid_for_inlined_node(&'tcx self, node_id: ast::NodeId) -> Option<DefId>;
253 fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
254 -> Option<Mir<'tcx>>;
255 fn is_item_mir_available(&self, def: DefId) -> bool;
257 // This is basically a 1-based range of ints, which is a little
258 // silly - I may fix that.
259 fn crates(&self) -> Vec<ast::CrateNum>;
260 fn used_libraries(&self) -> Vec<(String, NativeLibraryKind)>;
261 fn used_link_args(&self) -> Vec<String>;
264 fn metadata_filename(&self) -> &str;
265 fn metadata_section_name(&self, target: &Target) -> &str;
266 fn encode_type<'a>(&self,
267 tcx: TyCtxt<'a, 'tcx, 'tcx>,
269 def_id_to_string: for<'b> fn(TyCtxt<'b, 'tcx, 'tcx>, DefId) -> String)
271 fn used_crates(&self, prefer: LinkagePreference) -> Vec<(ast::CrateNum, Option<PathBuf>)>;
272 fn used_crate_source(&self, cnum: ast::CrateNum) -> CrateSource;
273 fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<ast::CrateNum>;
274 fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
275 reexports: &def::ExportMap,
276 link_meta: &LinkMeta,
278 mir_map: &MirMap<'tcx>,
279 krate: &hir::Crate) -> Vec<u8>;
280 fn metadata_encoding_version(&self) -> &[u8];
284 pub fn visit<'ast,V>(&'ast self, visitor: &mut V)
285 where V: Visitor<'ast>
288 InlinedItem::Item(_, ref i) => visitor.visit_item(&i),
289 InlinedItem::Foreign(_, ref i) => visitor.visit_foreign_item(&i),
290 InlinedItem::TraitItem(_, ref ti) => visitor.visit_trait_item(ti),
291 InlinedItem::ImplItem(_, ref ii) => visitor.visit_impl_item(ii),
296 // FIXME: find a better place for this?
297 pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
298 let mut err_count = 0;
300 let mut say = |s: &str| {
302 (_, None) => bug!("{}", s),
303 (Some(sp), Some(sess)) => sess.span_err(sp, s),
304 (None, Some(sess)) => sess.err(s),
309 say("crate name must not be empty");
312 if c.is_alphanumeric() { continue }
313 if c == '_' { continue }
314 say(&format!("invalid character `{}` in crate name: `{}`", c, s));
319 sess.unwrap().abort_if_errors();
323 /// A dummy crate store that does not support any non-local crates,
324 /// for test purposes.
325 pub struct DummyCrateStore;
326 #[allow(unused_variables)]
327 impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
329 fn stability(&self, def: DefId) -> Option<attr::Stability> { bug!("stability") }
330 fn deprecation(&self, def: DefId) -> Option<attr::Deprecation> { bug!("deprecation") }
331 fn visibility(&self, def: DefId) -> ty::Visibility { bug!("visibility") }
332 fn closure_kind(&self, def_id: DefId) -> ty::ClosureKind { bug!("closure_kind") }
333 fn closure_ty<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
334 -> ty::ClosureTy<'tcx> { bug!("closure_ty") }
335 fn item_variances(&self, def: DefId) -> ty::ItemVariances { bug!("item_variances") }
336 fn repr_attrs(&self, def: DefId) -> Vec<attr::ReprAttr> { bug!("repr_attrs") }
337 fn item_type<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
338 -> Ty<'tcx> { bug!("item_type") }
339 fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>> {
340 bug!("visible_parent_map")
342 fn item_name(&self, def: DefId) -> ast::Name { bug!("item_name") }
343 fn opt_item_name(&self, def: DefId) -> Option<ast::Name> { bug!("opt_item_name") }
344 fn item_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
345 -> ty::GenericPredicates<'tcx> { bug!("item_predicates") }
346 fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
347 -> ty::GenericPredicates<'tcx> { bug!("item_super_predicates") }
348 fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
349 -> &'tcx ty::Generics<'tcx> { bug!("item_generics") }
350 fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute> { bug!("item_attrs") }
351 fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef<'tcx>
352 { bug!("trait_def") }
353 fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>
355 fn method_arg_names(&self, did: DefId) -> Vec<String> { bug!("method_arg_names") }
356 fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId> { vec![] }
359 fn implementations_of_trait(&self, def_id: DefId) -> Vec<DefId> { vec![] }
360 fn provided_trait_methods<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
361 -> Vec<Rc<ty::Method<'tcx>>> { bug!("provided_trait_methods") }
362 fn trait_item_def_ids(&self, def: DefId)
363 -> Vec<ty::ImplOrTraitItemId> { bug!("trait_item_def_ids") }
364 fn def_index_for_def_key(&self,
367 -> Option<DefIndex> {
372 fn impl_items(&self, impl_def_id: DefId) -> Vec<ty::ImplOrTraitItemId>
373 { bug!("impl_items") }
374 fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
375 -> Option<ty::TraitRef<'tcx>> { bug!("impl_trait_ref") }
376 fn impl_polarity(&self, def: DefId) -> Option<hir::ImplPolarity> { bug!("impl_polarity") }
377 fn custom_coerce_unsized_kind(&self, def: DefId)
378 -> Option<ty::adjustment::CustomCoerceUnsized>
379 { bug!("custom_coerce_unsized_kind") }
380 fn associated_consts<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
381 -> Vec<Rc<ty::AssociatedConst<'tcx>>> { bug!("associated_consts") }
382 fn impl_parent(&self, def: DefId) -> Option<DefId> { bug!("impl_parent") }
384 // trait/impl-item info
385 fn trait_of_item(&self, def_id: DefId) -> Option<DefId> { bug!("trait_of_item") }
386 fn impl_or_trait_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
387 -> Option<ty::ImplOrTraitItem<'tcx>> { bug!("impl_or_trait_item") }
390 fn is_const_fn(&self, did: DefId) -> bool { bug!("is_const_fn") }
391 fn is_defaulted_trait(&self, did: DefId) -> bool { bug!("is_defaulted_trait") }
392 fn is_impl(&self, did: DefId) -> bool { bug!("is_impl") }
393 fn is_default_impl(&self, impl_did: DefId) -> bool { bug!("is_default_impl") }
394 fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool
395 { bug!("is_extern_item") }
396 fn is_foreign_item(&self, did: DefId) -> bool { bug!("is_foreign_item") }
397 fn is_static_method(&self, did: DefId) -> bool { bug!("is_static_method") }
398 fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool { false }
399 fn is_typedef(&self, did: DefId) -> bool { bug!("is_typedef") }
402 fn dylib_dependency_formats(&self, cnum: ast::CrateNum)
403 -> Vec<(ast::CrateNum, LinkagePreference)>
404 { bug!("dylib_dependency_formats") }
405 fn lang_items(&self, cnum: ast::CrateNum) -> Vec<(DefIndex, usize)>
406 { bug!("lang_items") }
407 fn missing_lang_items(&self, cnum: ast::CrateNum) -> Vec<lang_items::LangItem>
408 { bug!("missing_lang_items") }
409 fn is_staged_api(&self, cnum: ast::CrateNum) -> bool { bug!("is_staged_api") }
410 fn is_explicitly_linked(&self, cnum: ast::CrateNum) -> bool { bug!("is_explicitly_linked") }
411 fn is_allocator(&self, cnum: ast::CrateNum) -> bool { bug!("is_allocator") }
412 fn is_panic_runtime(&self, cnum: ast::CrateNum) -> bool { bug!("is_panic_runtime") }
413 fn panic_strategy(&self, cnum: ast::CrateNum) -> PanicStrategy {
414 bug!("panic_strategy")
416 fn extern_crate(&self, cnum: ast::CrateNum) -> Option<ExternCrate> { bug!("extern_crate") }
417 fn crate_attrs(&self, cnum: ast::CrateNum) -> Vec<ast::Attribute>
418 { bug!("crate_attrs") }
419 fn crate_name(&self, cnum: ast::CrateNum) -> InternedString { bug!("crate_name") }
420 fn original_crate_name(&self, cnum: ast::CrateNum) -> InternedString {
421 bug!("original_crate_name")
423 fn crate_hash(&self, cnum: ast::CrateNum) -> Svh { bug!("crate_hash") }
424 fn crate_disambiguator(&self, cnum: ast::CrateNum)
425 -> InternedString { bug!("crate_disambiguator") }
426 fn crate_struct_field_attrs(&self, cnum: ast::CrateNum)
427 -> FnvHashMap<DefId, Vec<ast::Attribute>>
428 { bug!("crate_struct_field_attrs") }
429 fn plugin_registrar_fn(&self, cnum: ast::CrateNum) -> Option<DefId>
430 { bug!("plugin_registrar_fn") }
431 fn native_libraries(&self, cnum: ast::CrateNum) -> Vec<(NativeLibraryKind, String)>
432 { bug!("native_libraries") }
433 fn reachable_ids(&self, cnum: ast::CrateNum) -> Vec<DefId> { bug!("reachable_ids") }
434 fn is_no_builtins(&self, cnum: ast::CrateNum) -> bool { bug!("is_no_builtins") }
437 fn def_key(&self, def: DefId) -> hir_map::DefKey { bug!("def_key") }
438 fn relative_def_path(&self, def: DefId) -> hir_map::DefPath { bug!("relative_def_path") }
439 fn variant_kind(&self, def_id: DefId) -> Option<VariantKind> { bug!("variant_kind") }
440 fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option<DefId>
441 { bug!("struct_ctor_def_id") }
442 fn tuple_struct_definition_if_ctor(&self, did: DefId) -> Option<DefId>
443 { bug!("tuple_struct_definition_if_ctor") }
444 fn struct_field_names(&self, def: DefId) -> Vec<ast::Name> { bug!("struct_field_names") }
445 fn item_children(&self, did: DefId) -> Vec<ChildItem> { bug!("item_children") }
446 fn crate_top_level_items(&self, cnum: ast::CrateNum) -> Vec<ChildItem>
447 { bug!("crate_top_level_items") }
450 fn maybe_get_item_ast<'a>(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
451 -> Option<(&'tcx InlinedItem, ast::NodeId)> {
452 bug!("maybe_get_item_ast")
454 fn local_node_for_inlined_defid(&'tcx self, def_id: DefId) -> Option<ast::NodeId> {
455 bug!("local_node_for_inlined_defid")
457 fn defid_for_inlined_node(&'tcx self, node_id: ast::NodeId) -> Option<DefId> {
458 bug!("defid_for_inlined_node")
461 fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
462 -> Option<Mir<'tcx>> { bug!("maybe_get_item_mir") }
463 fn is_item_mir_available(&self, def: DefId) -> bool {
464 bug!("is_item_mir_available")
467 // This is basically a 1-based range of ints, which is a little
468 // silly - I may fix that.
469 fn crates(&self) -> Vec<ast::CrateNum> { vec![] }
470 fn used_libraries(&self) -> Vec<(String, NativeLibraryKind)> { vec![] }
471 fn used_link_args(&self) -> Vec<String> { vec![] }
474 fn metadata_filename(&self) -> &str { bug!("metadata_filename") }
475 fn metadata_section_name(&self, target: &Target) -> &str { bug!("metadata_section_name") }
476 fn encode_type<'a>(&self,
477 tcx: TyCtxt<'a, 'tcx, 'tcx>,
479 def_id_to_string: for<'b> fn(TyCtxt<'b, 'tcx, 'tcx>, DefId) -> String)
483 fn used_crates(&self, prefer: LinkagePreference) -> Vec<(ast::CrateNum, Option<PathBuf>)>
485 fn used_crate_source(&self, cnum: ast::CrateNum) -> CrateSource { bug!("used_crate_source") }
486 fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<ast::CrateNum> { None }
487 fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
488 reexports: &def::ExportMap,
489 link_meta: &LinkMeta,
491 mir_map: &MirMap<'tcx>,
492 krate: &hir::Crate) -> Vec<u8> { vec![] }
493 fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") }
497 /// Metadata encoding and decoding can make use of thread-local encoding and
498 /// decoding contexts. These allow implementers of serialize::Encodable and
499 /// Decodable to access information and datastructures that would otherwise not
500 /// be available to them. For example, we can automatically translate def-id and
501 /// span information during decoding because the decoding context knows which
502 /// crate the data is decoded from. Or it allows to make ty::Ty decodable
503 /// because the context has access to the TyCtxt that is needed for creating
504 /// ty::Ty instances.
506 /// Note, however, that this only works for RBML-based encoding and decoding at
509 use rbml::opaque::Encoder as OpaqueEncoder;
510 use rbml::opaque::Decoder as OpaqueDecoder;
514 use ty::{self, Ty, TyCtxt};
515 use ty::subst::Substs;
516 use hir::def_id::DefId;
518 pub trait EncodingContext<'tcx> {
519 fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx>;
520 fn encode_ty(&self, encoder: &mut OpaqueEncoder, t: Ty<'tcx>);
521 fn encode_substs(&self, encoder: &mut OpaqueEncoder, substs: &Substs<'tcx>);
524 /// Marker type used for the TLS slot.
525 /// The type context cannot be used directly because the TLS
526 /// in libstd doesn't allow types generic over lifetimes.
530 static TLS_ENCODING: Cell<Option<*const TlsPayload>> = Cell::new(None)
533 /// Execute f after pushing the given EncodingContext onto the TLS stack.
534 pub fn enter_encoding_context<'tcx, F, R>(ecx: &EncodingContext<'tcx>,
535 encoder: &mut OpaqueEncoder,
537 where F: FnOnce(&EncodingContext<'tcx>, &mut OpaqueEncoder) -> R
539 let tls_payload = (ecx as *const _, encoder as *mut _);
540 let tls_ptr = &tls_payload as *const _ as *const TlsPayload;
541 TLS_ENCODING.with(|tls| {
542 let prev = tls.get();
543 tls.set(Some(tls_ptr));
544 let ret = f(ecx, encoder);
550 /// Execute f with access to the thread-local encoding context and
551 /// rbml encoder. This function will panic if the encoder passed in and the
552 /// context encoder are not the same.
554 /// Note that this method is 'practically' safe due to its checking that the
555 /// encoder passed in is the same as the one in TLS, but it would still be
556 /// possible to construct cases where the EncodingContext is exchanged
557 /// while the same encoder is used, thus working with a wrong context.
558 pub fn with_encoding_context<'tcx, E, F, R>(encoder: &mut E, f: F) -> R
559 where F: FnOnce(&EncodingContext<'tcx>, &mut OpaqueEncoder) -> R,
560 E: serialize::Encoder
563 unsafe_with_encoding_context(|ecx, tls_encoder| {
564 assert!(encoder as *mut _ as usize == tls_encoder as *mut _ as usize);
566 let ecx: &EncodingContext<'tcx> = mem::transmute(ecx);
573 /// Execute f with access to the thread-local encoding context and
575 pub unsafe fn unsafe_with_encoding_context<F, R>(f: F) -> R
576 where F: FnOnce(&EncodingContext, &mut OpaqueEncoder) -> R
578 TLS_ENCODING.with(|tls| {
579 let tls = tls.get().unwrap();
580 let tls_payload = tls as *mut (&EncodingContext, &mut OpaqueEncoder);
581 f((*tls_payload).0, (*tls_payload).1)
585 pub trait DecodingContext<'tcx> {
586 fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx>;
587 fn decode_ty(&self, decoder: &mut OpaqueDecoder) -> ty::Ty<'tcx>;
588 fn decode_substs(&self, decoder: &mut OpaqueDecoder) -> &'tcx Substs<'tcx>;
589 fn translate_def_id(&self, def_id: DefId) -> DefId;
593 static TLS_DECODING: Cell<Option<*const TlsPayload>> = Cell::new(None)
596 /// Execute f after pushing the given DecodingContext onto the TLS stack.
597 pub fn enter_decoding_context<'tcx, F, R>(dcx: &DecodingContext<'tcx>,
598 decoder: &mut OpaqueDecoder,
600 where F: FnOnce(&DecodingContext<'tcx>, &mut OpaqueDecoder) -> R
602 let tls_payload = (dcx as *const _, decoder as *mut _);
603 let tls_ptr = &tls_payload as *const _ as *const TlsPayload;
604 TLS_DECODING.with(|tls| {
605 let prev = tls.get();
606 tls.set(Some(tls_ptr));
607 let ret = f(dcx, decoder);
613 /// Execute f with access to the thread-local decoding context and
614 /// rbml decoder. This function will panic if the decoder passed in and the
615 /// context decoder are not the same.
617 /// Note that this method is 'practically' safe due to its checking that the
618 /// decoder passed in is the same as the one in TLS, but it would still be
619 /// possible to construct cases where the DecodingContext is exchanged
620 /// while the same decoder is used, thus working with a wrong context.
621 pub fn with_decoding_context<'decoder, 'tcx, D, F, R>(d: &'decoder mut D, f: F) -> R
622 where D: serialize::Decoder,
623 F: FnOnce(&DecodingContext<'tcx>,
624 &mut OpaqueDecoder) -> R,
628 unsafe_with_decoding_context(|dcx, decoder| {
629 assert!((d as *mut _ as usize) == (decoder as *mut _ as usize));
631 let dcx: &DecodingContext<'tcx> = mem::transmute(dcx);
638 /// Execute f with access to the thread-local decoding context and
640 pub unsafe fn unsafe_with_decoding_context<F, R>(f: F) -> R
641 where F: FnOnce(&DecodingContext, &mut OpaqueDecoder) -> R
643 TLS_DECODING.with(|tls| {
644 let tls = tls.get().unwrap();
645 let tls_payload = tls as *mut (&DecodingContext, &mut OpaqueDecoder);
646 f((*tls_payload).0, (*tls_payload).1)