]>
Commit | Line | Data |
---|---|---|
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 |
25 | use hir::svh::Svh; |
26 | use hir::map as hir_map; | |
27 | use hir::def::{self, Def}; | |
92a42be0 | 28 | use middle::lang_items; |
54a0048b SL |
29 | use ty::{self, Ty, TyCtxt, VariantKind}; |
30 | use hir::def_id::{DefId, DefIndex}; | |
9cc50fc6 | 31 | use mir::repr::Mir; |
7453a54e | 32 | use mir::mir_map::MirMap; |
92a42be0 SL |
33 | use session::Session; |
34 | use session::search_paths::PathKind; | |
54a0048b | 35 | use util::nodemap::{FnvHashMap, NodeMap, NodeSet, DefIdMap}; |
92a42be0 SL |
36 | use std::any::Any; |
37 | use std::cell::RefCell; | |
38 | use std::rc::Rc; | |
39 | use std::path::PathBuf; | |
40 | use syntax::ast; | |
92a42be0 SL |
41 | use syntax::attr; |
42 | use syntax::codemap::Span; | |
43 | use syntax::ptr::P; | |
54a0048b | 44 | use syntax::parse::token::InternedString; |
92a42be0 | 45 | use rustc_back::target::Target; |
54a0048b SL |
46 | use hir; |
47 | use hir::intravisit::{IdVisitor, IdVisitingOperation, Visitor}; | |
92a42be0 SL |
48 | |
49 | pub use self::DefLike::{DlDef, DlField, DlImpl}; | |
50 | pub use self::NativeLibraryKind::{NativeStatic, NativeFramework, NativeUnknown}; | |
51 | ||
52 | // lonely orphan structs and enums looking for a better home | |
53 | ||
54 | #[derive(Clone, Debug)] | |
55 | pub 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)] | |
63 | pub 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)] | |
70 | pub enum LinkagePreference { | |
71 | RequireDynamic, | |
72 | RequireStatic, | |
73 | } | |
74 | ||
75 | enum_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)] | |
86 | pub 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)] | |
96 | pub 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 |
105 | pub 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. | |
114 | pub const LOCAL_CRATE: ast::CrateNum = 0; | |
115 | ||
116 | pub struct ChildItem { | |
117 | pub def: DefLike, | |
118 | pub name: ast::Name, | |
54a0048b | 119 | pub vis: ty::Visibility, |
92a42be0 SL |
120 | } |
121 | ||
122 | pub 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)] |
129 | pub 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. | |
156 | pub 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 | ||
284 | impl 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? | |
303 | pub 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. | |
331 | pub struct DummyCrateStore; | |
332 | #[allow(unused_variables)] | |
333 | impl<'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. | |
494 | pub 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 | } |