]> git.proxmox.com Git - rustc.git/blame - src/librustc/middle/cstore.rs
Imported Upstream version 1.9.0+dfsg1
[rustc.git] / src / librustc / middle / cstore.rs
CommitLineData
92a42be0
SL
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
54a0048b
SL
25use hir::svh::Svh;
26use hir::map as hir_map;
27use hir::def::{self, Def};
92a42be0 28use middle::lang_items;
54a0048b
SL
29use ty::{self, Ty, TyCtxt, VariantKind};
30use hir::def_id::{DefId, DefIndex};
9cc50fc6 31use mir::repr::Mir;
7453a54e 32use mir::mir_map::MirMap;
92a42be0
SL
33use session::Session;
34use session::search_paths::PathKind;
54a0048b 35use util::nodemap::{FnvHashMap, NodeMap, NodeSet, DefIdMap};
92a42be0
SL
36use std::any::Any;
37use std::cell::RefCell;
38use std::rc::Rc;
39use std::path::PathBuf;
40use syntax::ast;
92a42be0
SL
41use syntax::attr;
42use syntax::codemap::Span;
43use syntax::ptr::P;
54a0048b 44use syntax::parse::token::InternedString;
92a42be0 45use rustc_back::target::Target;
54a0048b
SL
46use hir;
47use hir::intravisit::{IdVisitor, IdVisitingOperation, Visitor};
92a42be0
SL
48
49pub use self::DefLike::{DlDef, DlField, DlImpl};
50pub use self::NativeLibraryKind::{NativeStatic, NativeFramework, NativeUnknown};
51
52// lonely orphan structs and enums looking for a better home
53
54#[derive(Clone, Debug)]
55pub struct LinkMeta {
56 pub crate_name: String,
57 pub crate_hash: Svh,
58}
59
60// Where a crate came from on the local filesystem. One of these two options
61// must be non-None.
62#[derive(PartialEq, Clone, Debug)]
63pub struct CrateSource {
64 pub dylib: Option<(PathBuf, PathKind)>,
65 pub rlib: Option<(PathBuf, PathKind)>,
66 pub cnum: ast::CrateNum,
67}
68
69#[derive(Copy, Debug, PartialEq, Clone)]
70pub enum LinkagePreference {
71 RequireDynamic,
72 RequireStatic,
73}
74
75enum_from_u32! {
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
81 }
82}
83
84// Something that a name can resolve to.
85#[derive(Copy, Clone, Debug)]
86pub enum DefLike {
7453a54e 87 DlDef(Def),
92a42be0
SL
88 DlImpl(DefId),
89 DlField
90}
91
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
94/// that we trans.
95#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
96pub enum InlinedItem {
97 Item(P<hir::Item>),
98 TraitItem(DefId /* impl id */, P<hir::TraitItem>),
99 ImplItem(DefId /* impl id */, P<hir::ImplItem>),
100 Foreign(P<hir::ForeignItem>),
101}
102
103/// A borrowed version of `hir::InlinedItem`.
9cc50fc6 104#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
92a42be0
SL
105pub enum InlinedItemRef<'a> {
106 Item(&'a hir::Item),
107 TraitItem(DefId, &'a hir::TraitItem),
108 ImplItem(DefId, &'a hir::ImplItem),
109 Foreign(&'a hir::ForeignItem)
110}
111
112/// Item definitions in the currently-compiled crate would have the CrateNum
113/// LOCAL_CRATE in their DefId.
114pub const LOCAL_CRATE: ast::CrateNum = 0;
115
116pub struct ChildItem {
117 pub def: DefLike,
118 pub name: ast::Name,
54a0048b 119 pub vis: ty::Visibility,
92a42be0
SL
120}
121
122pub enum FoundAst<'ast> {
123 Found(&'ast InlinedItem),
54a0048b 124 FoundParent(DefId, &'ast hir::Item),
92a42be0
SL
125 NotFound,
126}
127
54a0048b
SL
128#[derive(Copy, Clone, Debug)]
129pub struct ExternCrate {
130 /// def_id of an `extern crate` in the current crate that caused
131 /// this crate to be loaded; note that there could be multiple
132 /// such ids
133 pub def_id: DefId,
134
135 /// span of the extern crate that caused this to be loaded
136 pub span: Span,
137
138 /// If true, then this crate is the crate named by the extern
139 /// crate referenced above. If false, then this crate is a dep
140 /// of the crate.
141 pub direct: bool,
142
143 /// Number of links to reach the extern crate `def_id`
144 /// declaration; used to select the extern crate with the shortest
145 /// path
146 pub path_len: usize,
147}
148
92a42be0
SL
149/// A store of Rust crates, through with their metadata
150/// can be accessed.
151///
152/// The `: Any` bound is a temporary measure that allows access
153/// to the backing `rustc_metadata::cstore::CStore` object. It
154/// will be removed in the near future - if you need to access
155/// internal APIs, please tell us.
156pub trait CrateStore<'tcx> : Any {
157 // item info
158 fn stability(&self, def: DefId) -> Option<attr::Stability>;
9cc50fc6 159 fn deprecation(&self, def: DefId) -> Option<attr::Deprecation>;
54a0048b
SL
160 fn visibility(&self, def: DefId) -> ty::Visibility;
161 fn closure_kind(&self, tcx: &TyCtxt<'tcx>, def_id: DefId)
92a42be0 162 -> ty::ClosureKind;
54a0048b 163 fn closure_ty(&self, tcx: &TyCtxt<'tcx>, def_id: DefId)
92a42be0
SL
164 -> ty::ClosureTy<'tcx>;
165 fn item_variances(&self, def: DefId) -> ty::ItemVariances;
166 fn repr_attrs(&self, def: DefId) -> Vec<attr::ReprAttr>;
54a0048b 167 fn item_type(&self, tcx: &TyCtxt<'tcx>, def: DefId)
92a42be0 168 -> ty::TypeScheme<'tcx>;
54a0048b 169 fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>>;
92a42be0 170 fn item_name(&self, def: DefId) -> ast::Name;
54a0048b 171 fn item_predicates(&self, tcx: &TyCtxt<'tcx>, def: DefId)
92a42be0 172 -> ty::GenericPredicates<'tcx>;
54a0048b 173 fn item_super_predicates(&self, tcx: &TyCtxt<'tcx>, def: DefId)
92a42be0
SL
174 -> ty::GenericPredicates<'tcx>;
175 fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>;
176 fn item_symbol(&self, def: DefId) -> String;
54a0048b
SL
177 fn trait_def(&self, tcx: &TyCtxt<'tcx>, def: DefId)-> ty::TraitDef<'tcx>;
178 fn adt_def(&self, tcx: &TyCtxt<'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>;
92a42be0
SL
179 fn method_arg_names(&self, did: DefId) -> Vec<String>;
180 fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId>;
181
182 // trait info
183 fn implementations_of_trait(&self, def_id: DefId) -> Vec<DefId>;
54a0048b 184 fn provided_trait_methods(&self, tcx: &TyCtxt<'tcx>, def: DefId)
92a42be0
SL
185 -> Vec<Rc<ty::Method<'tcx>>>;
186 fn trait_item_def_ids(&self, def: DefId)
187 -> Vec<ty::ImplOrTraitItemId>;
188
189 // impl info
190 fn impl_items(&self, impl_def_id: DefId) -> Vec<ty::ImplOrTraitItemId>;
54a0048b 191 fn impl_trait_ref(&self, tcx: &TyCtxt<'tcx>, def: DefId)
92a42be0
SL
192 -> Option<ty::TraitRef<'tcx>>;
193 fn impl_polarity(&self, def: DefId) -> Option<hir::ImplPolarity>;
194 fn custom_coerce_unsized_kind(&self, def: DefId)
195 -> Option<ty::adjustment::CustomCoerceUnsized>;
54a0048b 196 fn associated_consts(&self, tcx: &TyCtxt<'tcx>, def: DefId)
92a42be0 197 -> Vec<Rc<ty::AssociatedConst<'tcx>>>;
54a0048b 198 fn impl_parent(&self, impl_def_id: DefId) -> Option<DefId>;
92a42be0
SL
199
200 // trait/impl-item info
54a0048b 201 fn trait_of_item(&self, tcx: &TyCtxt<'tcx>, def_id: DefId)
92a42be0 202 -> Option<DefId>;
54a0048b
SL
203 fn impl_or_trait_item(&self, tcx: &TyCtxt<'tcx>, def: DefId)
204 -> Option<ty::ImplOrTraitItem<'tcx>>;
92a42be0
SL
205
206 // flags
207 fn is_const_fn(&self, did: DefId) -> bool;
208 fn is_defaulted_trait(&self, did: DefId) -> bool;
209 fn is_impl(&self, did: DefId) -> bool;
210 fn is_default_impl(&self, impl_did: DefId) -> bool;
54a0048b 211 fn is_extern_item(&self, tcx: &TyCtxt<'tcx>, did: DefId) -> bool;
92a42be0
SL
212 fn is_static_method(&self, did: DefId) -> bool;
213 fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool;
214 fn is_typedef(&self, did: DefId) -> bool;
215
216 // crate metadata
217 fn dylib_dependency_formats(&self, cnum: ast::CrateNum)
218 -> Vec<(ast::CrateNum, LinkagePreference)>;
219 fn lang_items(&self, cnum: ast::CrateNum) -> Vec<(DefIndex, usize)>;
220 fn missing_lang_items(&self, cnum: ast::CrateNum) -> Vec<lang_items::LangItem>;
221 fn is_staged_api(&self, cnum: ast::CrateNum) -> bool;
222 fn is_explicitly_linked(&self, cnum: ast::CrateNum) -> bool;
223 fn is_allocator(&self, cnum: ast::CrateNum) -> bool;
54a0048b 224 fn extern_crate(&self, cnum: ast::CrateNum) -> Option<ExternCrate>;
92a42be0 225 fn crate_attrs(&self, cnum: ast::CrateNum) -> Vec<ast::Attribute>;
54a0048b
SL
226 /// The name of the crate as it is referred to in source code of the current
227 /// crate.
228 fn crate_name(&self, cnum: ast::CrateNum) -> InternedString;
229 /// The name of the crate as it is stored in the crate's metadata.
230 fn original_crate_name(&self, cnum: ast::CrateNum) -> InternedString;
92a42be0 231 fn crate_hash(&self, cnum: ast::CrateNum) -> Svh;
54a0048b 232 fn crate_disambiguator(&self, cnum: ast::CrateNum) -> InternedString;
92a42be0
SL
233 fn crate_struct_field_attrs(&self, cnum: ast::CrateNum)
234 -> FnvHashMap<DefId, Vec<ast::Attribute>>;
235 fn plugin_registrar_fn(&self, cnum: ast::CrateNum) -> Option<DefId>;
236 fn native_libraries(&self, cnum: ast::CrateNum) -> Vec<(NativeLibraryKind, String)>;
237 fn reachable_ids(&self, cnum: ast::CrateNum) -> Vec<DefId>;
238
239 // resolve
54a0048b
SL
240 fn def_key(&self, def: DefId) -> hir_map::DefKey;
241 fn relative_def_path(&self, def: DefId) -> hir_map::DefPath;
7453a54e
SL
242 fn variant_kind(&self, def_id: DefId) -> Option<VariantKind>;
243 fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option<DefId>;
92a42be0
SL
244 fn tuple_struct_definition_if_ctor(&self, did: DefId) -> Option<DefId>;
245 fn struct_field_names(&self, def: DefId) -> Vec<ast::Name>;
246 fn item_children(&self, did: DefId) -> Vec<ChildItem>;
247 fn crate_top_level_items(&self, cnum: ast::CrateNum) -> Vec<ChildItem>;
248
249 // misc. metadata
54a0048b 250 fn maybe_get_item_ast(&'tcx self, tcx: &TyCtxt<'tcx>, def: DefId)
92a42be0 251 -> FoundAst<'tcx>;
54a0048b 252 fn maybe_get_item_mir(&self, tcx: &TyCtxt<'tcx>, def: DefId)
9cc50fc6 253 -> Option<Mir<'tcx>>;
7453a54e
SL
254 fn is_item_mir_available(&self, def: DefId) -> bool;
255
92a42be0
SL
256 // This is basically a 1-based range of ints, which is a little
257 // silly - I may fix that.
258 fn crates(&self) -> Vec<ast::CrateNum>;
259 fn used_libraries(&self) -> Vec<(String, NativeLibraryKind)>;
260 fn used_link_args(&self) -> Vec<String>;
261
262 // utility functions
263 fn metadata_filename(&self) -> &str;
264 fn metadata_section_name(&self, target: &Target) -> &str;
54a0048b
SL
265 fn encode_type(&self,
266 tcx: &TyCtxt<'tcx>,
267 ty: Ty<'tcx>,
268 def_id_to_string: fn(&TyCtxt<'tcx>, DefId) -> String)
269 -> Vec<u8>;
92a42be0
SL
270 fn used_crates(&self, prefer: LinkagePreference) -> Vec<(ast::CrateNum, Option<PathBuf>)>;
271 fn used_crate_source(&self, cnum: ast::CrateNum) -> CrateSource;
272 fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<ast::CrateNum>;
273 fn encode_metadata(&self,
54a0048b 274 tcx: &TyCtxt<'tcx>,
92a42be0
SL
275 reexports: &def::ExportMap,
276 item_symbols: &RefCell<NodeMap<String>>,
277 link_meta: &LinkMeta,
278 reachable: &NodeSet,
7453a54e 279 mir_map: &MirMap<'tcx>,
92a42be0
SL
280 krate: &hir::Crate) -> Vec<u8>;
281 fn metadata_encoding_version(&self) -> &[u8];
282}
283
284impl InlinedItem {
285 pub fn visit<'ast,V>(&'ast self, visitor: &mut V)
286 where V: Visitor<'ast>
287 {
288 match *self {
7453a54e
SL
289 InlinedItem::Item(ref i) => visitor.visit_item(&i),
290 InlinedItem::Foreign(ref i) => visitor.visit_foreign_item(&i),
92a42be0
SL
291 InlinedItem::TraitItem(_, ref ti) => visitor.visit_trait_item(ti),
292 InlinedItem::ImplItem(_, ref ii) => visitor.visit_impl_item(ii),
293 }
294 }
295
296 pub fn visit_ids<O: IdVisitingOperation>(&self, operation: &mut O) {
297 let mut id_visitor = IdVisitor::new(operation);
298 self.visit(&mut id_visitor);
299 }
300}
301
302// FIXME: find a better place for this?
303pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
7453a54e
SL
304 let mut err_count = 0;
305 {
306 let mut say = |s: &str| {
307 match (sp, sess) {
54a0048b 308 (_, None) => bug!("{}", s),
7453a54e
SL
309 (Some(sp), Some(sess)) => sess.span_err(sp, s),
310 (None, Some(sess)) => sess.err(s),
311 }
312 err_count += 1;
313 };
314 if s.is_empty() {
315 say("crate name must not be empty");
316 }
317 for c in s.chars() {
318 if c.is_alphanumeric() { continue }
319 if c == '_' { continue }
320 say(&format!("invalid character `{}` in crate name: `{}`", c, s));
92a42be0 321 }
92a42be0 322 }
7453a54e
SL
323
324 if err_count > 0 {
325 sess.unwrap().abort_if_errors();
92a42be0
SL
326 }
327}
328
329/// A dummy crate store that does not support any non-local crates,
330/// for test purposes.
331pub struct DummyCrateStore;
332#[allow(unused_variables)]
333impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
334 // item info
54a0048b
SL
335 fn stability(&self, def: DefId) -> Option<attr::Stability> { bug!("stability") }
336 fn deprecation(&self, def: DefId) -> Option<attr::Deprecation> { bug!("deprecation") }
337 fn visibility(&self, def: DefId) -> ty::Visibility { bug!("visibility") }
338 fn closure_kind(&self, tcx: &TyCtxt<'tcx>, def_id: DefId)
339 -> ty::ClosureKind { bug!("closure_kind") }
340 fn closure_ty(&self, tcx: &TyCtxt<'tcx>, def_id: DefId)
341 -> ty::ClosureTy<'tcx> { bug!("closure_ty") }
342 fn item_variances(&self, def: DefId) -> ty::ItemVariances { bug!("item_variances") }
343 fn repr_attrs(&self, def: DefId) -> Vec<attr::ReprAttr> { bug!("repr_attrs") }
344 fn item_type(&self, tcx: &TyCtxt<'tcx>, def: DefId)
345 -> ty::TypeScheme<'tcx> { bug!("item_type") }
346 fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>> {
347 bug!("visible_parent_map")
348 }
349 fn item_name(&self, def: DefId) -> ast::Name { bug!("item_name") }
350 fn item_predicates(&self, tcx: &TyCtxt<'tcx>, def: DefId)
351 -> ty::GenericPredicates<'tcx> { bug!("item_predicates") }
352 fn item_super_predicates(&self, tcx: &TyCtxt<'tcx>, def: DefId)
353 -> ty::GenericPredicates<'tcx> { bug!("item_super_predicates") }
354 fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute> { bug!("item_attrs") }
355 fn item_symbol(&self, def: DefId) -> String { bug!("item_symbol") }
356 fn trait_def(&self, tcx: &TyCtxt<'tcx>, def: DefId)-> ty::TraitDef<'tcx>
357 { bug!("trait_def") }
358 fn adt_def(&self, tcx: &TyCtxt<'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>
359 { bug!("adt_def") }
360 fn method_arg_names(&self, did: DefId) -> Vec<String> { bug!("method_arg_names") }
92a42be0
SL
361 fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId> { vec![] }
362
363 // trait info
364 fn implementations_of_trait(&self, def_id: DefId) -> Vec<DefId> { vec![] }
54a0048b
SL
365 fn provided_trait_methods(&self, tcx: &TyCtxt<'tcx>, def: DefId)
366 -> Vec<Rc<ty::Method<'tcx>>> { bug!("provided_trait_methods") }
92a42be0 367 fn trait_item_def_ids(&self, def: DefId)
54a0048b 368 -> Vec<ty::ImplOrTraitItemId> { bug!("trait_item_def_ids") }
92a42be0
SL
369
370 // impl info
371 fn impl_items(&self, impl_def_id: DefId) -> Vec<ty::ImplOrTraitItemId>
54a0048b
SL
372 { bug!("impl_items") }
373 fn impl_trait_ref(&self, tcx: &TyCtxt<'tcx>, def: DefId)
374 -> Option<ty::TraitRef<'tcx>> { bug!("impl_trait_ref") }
375 fn impl_polarity(&self, def: DefId) -> Option<hir::ImplPolarity> { bug!("impl_polarity") }
92a42be0
SL
376 fn custom_coerce_unsized_kind(&self, def: DefId)
377 -> Option<ty::adjustment::CustomCoerceUnsized>
54a0048b
SL
378 { bug!("custom_coerce_unsized_kind") }
379 fn associated_consts(&self, tcx: &TyCtxt<'tcx>, def: DefId)
380 -> Vec<Rc<ty::AssociatedConst<'tcx>>> { bug!("associated_consts") }
381 fn impl_parent(&self, def: DefId) -> Option<DefId> { bug!("impl_parent") }
92a42be0
SL
382
383 // trait/impl-item info
54a0048b
SL
384 fn trait_of_item(&self, tcx: &TyCtxt<'tcx>, def_id: DefId)
385 -> Option<DefId> { bug!("trait_of_item") }
386 fn impl_or_trait_item(&self, tcx: &TyCtxt<'tcx>, def: DefId)
387 -> Option<ty::ImplOrTraitItem<'tcx>> { bug!("impl_or_trait_item") }
92a42be0
SL
388
389 // flags
54a0048b
SL
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(&self, tcx: &TyCtxt<'tcx>, did: DefId) -> bool { bug!("is_extern_item") }
395 fn is_static_method(&self, did: DefId) -> bool { bug!("is_static_method") }
92a42be0 396 fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool { false }
54a0048b 397 fn is_typedef(&self, did: DefId) -> bool { bug!("is_typedef") }
92a42be0
SL
398
399 // crate metadata
400 fn dylib_dependency_formats(&self, cnum: ast::CrateNum)
401 -> Vec<(ast::CrateNum, LinkagePreference)>
54a0048b 402 { bug!("dylib_dependency_formats") }
92a42be0 403 fn lang_items(&self, cnum: ast::CrateNum) -> Vec<(DefIndex, usize)>
54a0048b 404 { bug!("lang_items") }
92a42be0 405 fn missing_lang_items(&self, cnum: ast::CrateNum) -> Vec<lang_items::LangItem>
54a0048b
SL
406 { bug!("missing_lang_items") }
407 fn is_staged_api(&self, cnum: ast::CrateNum) -> bool { bug!("is_staged_api") }
408 fn is_explicitly_linked(&self, cnum: ast::CrateNum) -> bool { bug!("is_explicitly_linked") }
409 fn is_allocator(&self, cnum: ast::CrateNum) -> bool { bug!("is_allocator") }
410 fn extern_crate(&self, cnum: ast::CrateNum) -> Option<ExternCrate> { bug!("extern_crate") }
92a42be0 411 fn crate_attrs(&self, cnum: ast::CrateNum) -> Vec<ast::Attribute>
54a0048b
SL
412 { bug!("crate_attrs") }
413 fn crate_name(&self, cnum: ast::CrateNum) -> InternedString { bug!("crate_name") }
414 fn original_crate_name(&self, cnum: ast::CrateNum) -> InternedString {
415 bug!("original_crate_name")
416 }
417 fn crate_hash(&self, cnum: ast::CrateNum) -> Svh { bug!("crate_hash") }
418 fn crate_disambiguator(&self, cnum: ast::CrateNum)
419 -> InternedString { bug!("crate_disambiguator") }
92a42be0
SL
420 fn crate_struct_field_attrs(&self, cnum: ast::CrateNum)
421 -> FnvHashMap<DefId, Vec<ast::Attribute>>
54a0048b 422 { bug!("crate_struct_field_attrs") }
92a42be0 423 fn plugin_registrar_fn(&self, cnum: ast::CrateNum) -> Option<DefId>
54a0048b 424 { bug!("plugin_registrar_fn") }
92a42be0 425 fn native_libraries(&self, cnum: ast::CrateNum) -> Vec<(NativeLibraryKind, String)>
54a0048b
SL
426 { bug!("native_libraries") }
427 fn reachable_ids(&self, cnum: ast::CrateNum) -> Vec<DefId> { bug!("reachable_ids") }
92a42be0
SL
428
429 // resolve
54a0048b
SL
430 fn def_key(&self, def: DefId) -> hir_map::DefKey { bug!("def_key") }
431 fn relative_def_path(&self, def: DefId) -> hir_map::DefPath { bug!("relative_def_path") }
432 fn variant_kind(&self, def_id: DefId) -> Option<VariantKind> { bug!("variant_kind") }
7453a54e 433 fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option<DefId>
54a0048b 434 { bug!("struct_ctor_def_id") }
92a42be0 435 fn tuple_struct_definition_if_ctor(&self, did: DefId) -> Option<DefId>
54a0048b
SL
436 { bug!("tuple_struct_definition_if_ctor") }
437 fn struct_field_names(&self, def: DefId) -> Vec<ast::Name> { bug!("struct_field_names") }
438 fn item_children(&self, did: DefId) -> Vec<ChildItem> { bug!("item_children") }
92a42be0 439 fn crate_top_level_items(&self, cnum: ast::CrateNum) -> Vec<ChildItem>
54a0048b 440 { bug!("crate_top_level_items") }
92a42be0
SL
441
442 // misc. metadata
54a0048b
SL
443 fn maybe_get_item_ast(&'tcx self, tcx: &TyCtxt<'tcx>, def: DefId)
444 -> FoundAst<'tcx> { bug!("maybe_get_item_ast") }
445 fn maybe_get_item_mir(&self, tcx: &TyCtxt<'tcx>, def: DefId)
446 -> Option<Mir<'tcx>> { bug!("maybe_get_item_mir") }
7453a54e 447 fn is_item_mir_available(&self, def: DefId) -> bool {
54a0048b 448 bug!("is_item_mir_available")
7453a54e 449 }
9cc50fc6 450
92a42be0
SL
451 // This is basically a 1-based range of ints, which is a little
452 // silly - I may fix that.
453 fn crates(&self) -> Vec<ast::CrateNum> { vec![] }
454 fn used_libraries(&self) -> Vec<(String, NativeLibraryKind)> { vec![] }
455 fn used_link_args(&self) -> Vec<String> { vec![] }
456
457 // utility functions
54a0048b
SL
458 fn metadata_filename(&self) -> &str { bug!("metadata_filename") }
459 fn metadata_section_name(&self, target: &Target) -> &str { bug!("metadata_section_name") }
460 fn encode_type(&self,
461 tcx: &TyCtxt<'tcx>,
462 ty: Ty<'tcx>,
463 def_id_to_string: fn(&TyCtxt<'tcx>, DefId) -> String)
464 -> Vec<u8> {
465 bug!("encode_type")
466 }
92a42be0
SL
467 fn used_crates(&self, prefer: LinkagePreference) -> Vec<(ast::CrateNum, Option<PathBuf>)>
468 { vec![] }
54a0048b 469 fn used_crate_source(&self, cnum: ast::CrateNum) -> CrateSource { bug!("used_crate_source") }
92a42be0
SL
470 fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<ast::CrateNum> { None }
471 fn encode_metadata(&self,
54a0048b 472 tcx: &TyCtxt<'tcx>,
92a42be0
SL
473 reexports: &def::ExportMap,
474 item_symbols: &RefCell<NodeMap<String>>,
475 link_meta: &LinkMeta,
476 reachable: &NodeSet,
7453a54e 477 mir_map: &MirMap<'tcx>,
92a42be0 478 krate: &hir::Crate) -> Vec<u8> { vec![] }
54a0048b 479 fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") }
92a42be0 480}
9cc50fc6
SL
481
482
483/// Metadata encoding and decoding can make use of thread-local encoding and
484/// decoding contexts. These allow implementers of serialize::Encodable and
485/// Decodable to access information and datastructures that would otherwise not
486/// be available to them. For example, we can automatically translate def-id and
487/// span information during decoding because the decoding context knows which
488/// crate the data is decoded from. Or it allows to make ty::Ty decodable
54a0048b 489/// because the context has access to the TyCtxt that is needed for creating
9cc50fc6
SL
490/// ty::Ty instances.
491///
492/// Note, however, that this only works for RBML-based encoding and decoding at
493/// the moment.
494pub mod tls {
495 use rbml::opaque::Encoder as OpaqueEncoder;
496 use rbml::opaque::Decoder as OpaqueDecoder;
497 use serialize;
7453a54e 498 use std::cell::Cell;
9cc50fc6 499 use std::mem;
54a0048b
SL
500 use ty::{self, Ty, TyCtxt};
501 use ty::subst::Substs;
502 use hir::def_id::DefId;
9cc50fc6
SL
503
504 pub trait EncodingContext<'tcx> {
54a0048b 505 fn tcx<'a>(&'a self) -> &'a TyCtxt<'tcx>;
9cc50fc6
SL
506 fn encode_ty(&self, encoder: &mut OpaqueEncoder, t: Ty<'tcx>);
507 fn encode_substs(&self, encoder: &mut OpaqueEncoder, substs: &Substs<'tcx>);
508 }
509
7453a54e
SL
510 /// Marker type used for the TLS slot.
511 /// The type context cannot be used directly because the TLS
9cc50fc6
SL
512 /// in libstd doesn't allow types generic over lifetimes.
513 struct TlsPayload;
514
7453a54e
SL
515 thread_local! {
516 static TLS_ENCODING: Cell<Option<*const TlsPayload>> = Cell::new(None)
517 }
9cc50fc6
SL
518
519 /// Execute f after pushing the given EncodingContext onto the TLS stack.
520 pub fn enter_encoding_context<'tcx, F, R>(ecx: &EncodingContext<'tcx>,
521 encoder: &mut OpaqueEncoder,
522 f: F) -> R
523 where F: FnOnce(&EncodingContext<'tcx>, &mut OpaqueEncoder) -> R
524 {
525 let tls_payload = (ecx as *const _, encoder as *mut _);
526 let tls_ptr = &tls_payload as *const _ as *const TlsPayload;
7453a54e
SL
527 TLS_ENCODING.with(|tls| {
528 let prev = tls.get();
529 tls.set(Some(tls_ptr));
530 let ret = f(ecx, encoder);
531 tls.set(prev);
532 return ret
533 })
9cc50fc6
SL
534 }
535
536 /// Execute f with access to the thread-local encoding context and
537 /// rbml encoder. This function will panic if the encoder passed in and the
538 /// context encoder are not the same.
539 ///
540 /// Note that this method is 'practically' safe due to its checking that the
541 /// encoder passed in is the same as the one in TLS, but it would still be
542 /// possible to construct cases where the EncodingContext is exchanged
543 /// while the same encoder is used, thus working with a wrong context.
544 pub fn with_encoding_context<'tcx, E, F, R>(encoder: &mut E, f: F) -> R
545 where F: FnOnce(&EncodingContext<'tcx>, &mut OpaqueEncoder) -> R,
546 E: serialize::Encoder
547 {
548 unsafe {
549 unsafe_with_encoding_context(|ecx, tls_encoder| {
550 assert!(encoder as *mut _ as usize == tls_encoder as *mut _ as usize);
551
552 let ecx: &EncodingContext<'tcx> = mem::transmute(ecx);
553
554 f(ecx, tls_encoder)
555 })
556 }
557 }
558
559 /// Execute f with access to the thread-local encoding context and
560 /// rbml encoder.
561 pub unsafe fn unsafe_with_encoding_context<F, R>(f: F) -> R
562 where F: FnOnce(&EncodingContext, &mut OpaqueEncoder) -> R
563 {
564 TLS_ENCODING.with(|tls| {
7453a54e
SL
565 let tls = tls.get().unwrap();
566 let tls_payload = tls as *mut (&EncodingContext, &mut OpaqueEncoder);
9cc50fc6
SL
567 f((*tls_payload).0, (*tls_payload).1)
568 })
569 }
570
571 pub trait DecodingContext<'tcx> {
54a0048b 572 fn tcx<'a>(&'a self) -> &'a TyCtxt<'tcx>;
9cc50fc6
SL
573 fn decode_ty(&self, decoder: &mut OpaqueDecoder) -> ty::Ty<'tcx>;
574 fn decode_substs(&self, decoder: &mut OpaqueDecoder) -> Substs<'tcx>;
575 fn translate_def_id(&self, def_id: DefId) -> DefId;
576 }
577
7453a54e
SL
578 thread_local! {
579 static TLS_DECODING: Cell<Option<*const TlsPayload>> = Cell::new(None)
580 }
9cc50fc6
SL
581
582 /// Execute f after pushing the given DecodingContext onto the TLS stack.
583 pub fn enter_decoding_context<'tcx, F, R>(dcx: &DecodingContext<'tcx>,
584 decoder: &mut OpaqueDecoder,
585 f: F) -> R
586 where F: FnOnce(&DecodingContext<'tcx>, &mut OpaqueDecoder) -> R
587 {
588 let tls_payload = (dcx as *const _, decoder as *mut _);
589 let tls_ptr = &tls_payload as *const _ as *const TlsPayload;
7453a54e
SL
590 TLS_DECODING.with(|tls| {
591 let prev = tls.get();
592 tls.set(Some(tls_ptr));
593 let ret = f(dcx, decoder);
594 tls.set(prev);
595 return ret
596 })
9cc50fc6
SL
597 }
598
599 /// Execute f with access to the thread-local decoding context and
600 /// rbml decoder. This function will panic if the decoder passed in and the
601 /// context decoder are not the same.
602 ///
603 /// Note that this method is 'practically' safe due to its checking that the
604 /// decoder passed in is the same as the one in TLS, but it would still be
605 /// possible to construct cases where the DecodingContext is exchanged
606 /// while the same decoder is used, thus working with a wrong context.
607 pub fn with_decoding_context<'decoder, 'tcx, D, F, R>(d: &'decoder mut D, f: F) -> R
608 where D: serialize::Decoder,
609 F: FnOnce(&DecodingContext<'tcx>,
610 &mut OpaqueDecoder) -> R,
611 'tcx: 'decoder
612 {
613 unsafe {
614 unsafe_with_decoding_context(|dcx, decoder| {
615 assert!((d as *mut _ as usize) == (decoder as *mut _ as usize));
616
617 let dcx: &DecodingContext<'tcx> = mem::transmute(dcx);
618
619 f(dcx, decoder)
620 })
621 }
622 }
623
624 /// Execute f with access to the thread-local decoding context and
625 /// rbml decoder.
626 pub unsafe fn unsafe_with_decoding_context<F, R>(f: F) -> R
627 where F: FnOnce(&DecodingContext, &mut OpaqueDecoder) -> R
628 {
629 TLS_DECODING.with(|tls| {
7453a54e
SL
630 let tls = tls.get().unwrap();
631 let tls_payload = tls as *mut (&DecodingContext, &mut OpaqueDecoder);
9cc50fc6
SL
632 f((*tls_payload).0, (*tls_payload).1)
633 })
634 }
635}