]> git.proxmox.com Git - rustc.git/blame - src/librustc/middle/lang_items.rs
Imported Upstream version 1.9.0+dfsg1
[rustc.git] / src / librustc / middle / lang_items.rs
CommitLineData
223e47cc
LB
1// Copyright 2012 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
223e47cc
LB
11// Detecting language items.
12//
13// Language items are items that represent concepts intrinsic to the language
14// itself. Examples are:
15//
1a4d82fc 16// * Traits that specify "kinds"; e.g. "Sync", "Send".
223e47cc 17//
970d7e83 18// * Traits that represent operators; e.g. "Add", "Sub", "Index".
223e47cc
LB
19//
20// * Functions called by the compiler itself.
21
1a4d82fc 22pub use self::LangItem::*;
223e47cc 23
7453a54e 24use dep_graph::DepNode;
54a0048b 25use hir::map as hir_map;
1a4d82fc 26use session::Session;
92a42be0 27use middle::cstore::CrateStore;
54a0048b
SL
28use hir::def_id::DefId;
29use ty;
1a4d82fc
JJ
30use middle::weak_lang_items;
31use util::nodemap::FnvHashMap;
223e47cc 32
b039eaaf
SL
33use syntax::ast;
34use syntax::attr::AttrMetaMethods;
1a4d82fc 35use syntax::parse::token::InternedString;
54a0048b
SL
36use hir::intravisit::Visitor;
37use hir;
1a4d82fc 38
1a4d82fc
JJ
39// The actual lang items defined come at the end of this file in one handy table.
40// So you probably just want to nip down to the end.
41macro_rules! lets_do_this {
42 (
43 $( $variant:ident, $name:expr, $method:ident; )*
44 ) => {
45
9346a6ac
AL
46
47enum_from_u32! {
48 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
49 pub enum LangItem {
50 $($variant,)*
51 }
223e47cc
LB
52}
53
54pub struct LanguageItems {
e9174d1e 55 pub items: Vec<Option<DefId>>,
1a4d82fc 56 pub missing: Vec<LangItem>,
223e47cc
LB
57}
58
970d7e83 59impl LanguageItems {
223e47cc 60 pub fn new() -> LanguageItems {
e9174d1e 61 fn foo(_: LangItem) -> Option<DefId> { None }
1a4d82fc 62
223e47cc 63 LanguageItems {
1a4d82fc
JJ
64 items: vec!($(foo($variant)),*),
65 missing: Vec::new(),
223e47cc
LB
66 }
67 }
68
7453a54e
SL
69 pub fn items(&self) -> &[Option<DefId>] {
70 &*self.items
223e47cc
LB
71 }
72
c34b1796 73 pub fn item_name(index: usize) -> &'static str {
9346a6ac 74 let item: Option<LangItem> = LangItem::from_u32(index as u32);
1a4d82fc
JJ
75 match item {
76 $( Some($variant) => $name, )*
77 None => "???"
223e47cc
LB
78 }
79 }
80
e9174d1e 81 pub fn require(&self, it: LangItem) -> Result<DefId, String> {
c34b1796 82 match self.items[it as usize] {
1a4d82fc
JJ
83 Some(id) => Ok(id),
84 None => {
85 Err(format!("requires `{}` lang_item",
c34b1796 86 LanguageItems::item_name(it as usize)))
1a4d82fc
JJ
87 }
88 }
223e47cc
LB
89 }
90
e9174d1e 91 pub fn require_owned_box(&self) -> Result<DefId, String> {
c1a9b12d
SL
92 self.require(OwnedBoxLangItem)
93 }
94
1a4d82fc 95 pub fn from_builtin_kind(&self, bound: ty::BuiltinBound)
e9174d1e 96 -> Result<DefId, String>
1a4d82fc
JJ
97 {
98 match bound {
99 ty::BoundSend => self.require(SendTraitLangItem),
100 ty::BoundSized => self.require(SizedTraitLangItem),
101 ty::BoundCopy => self.require(CopyTraitLangItem),
102 ty::BoundSync => self.require(SyncTraitLangItem),
103 }
223e47cc
LB
104 }
105
e9174d1e 106 pub fn to_builtin_kind(&self, id: DefId) -> Option<ty::BuiltinBound> {
1a4d82fc
JJ
107 if Some(id) == self.send_trait() {
108 Some(ty::BoundSend)
109 } else if Some(id) == self.sized_trait() {
110 Some(ty::BoundSized)
111 } else if Some(id) == self.copy_trait() {
112 Some(ty::BoundCopy)
113 } else if Some(id) == self.sync_trait() {
114 Some(ty::BoundSync)
115 } else {
116 None
117 }
223e47cc
LB
118 }
119
e9174d1e 120 pub fn fn_trait_kind(&self, id: DefId) -> Option<ty::ClosureKind> {
1a4d82fc 121 let def_id_kinds = [
54a0048b
SL
122 (self.fn_trait(), ty::ClosureKind::Fn),
123 (self.fn_mut_trait(), ty::ClosureKind::FnMut),
124 (self.fn_once_trait(), ty::ClosureKind::FnOnce),
1a4d82fc 125 ];
223e47cc 126
85aaf69f 127 for &(opt_def_id, kind) in &def_id_kinds {
1a4d82fc
JJ
128 if Some(id) == opt_def_id {
129 return Some(kind);
130 }
131 }
132
133 None
223e47cc 134 }
1a4d82fc
JJ
135
136 $(
137 #[allow(dead_code)]
e9174d1e 138 pub fn $method(&self) -> Option<DefId> {
c34b1796 139 self.items[$variant as usize]
1a4d82fc
JJ
140 }
141 )*
223e47cc
LB
142}
143
b039eaaf 144struct LanguageItemCollector<'a, 'tcx: 'a> {
970d7e83 145 items: LanguageItems,
223e47cc 146
b039eaaf
SL
147 ast_map: &'a hir_map::Map<'tcx>,
148
1a4d82fc 149 session: &'a Session,
223e47cc 150
c34b1796 151 item_refs: FnvHashMap<&'static str, usize>,
223e47cc
LB
152}
153
b039eaaf 154impl<'a, 'v, 'tcx> Visitor<'v> for LanguageItemCollector<'a, 'tcx> {
e9174d1e 155 fn visit_item(&mut self, item: &hir::Item) {
85aaf69f
SL
156 if let Some(value) = extract(&item.attrs) {
157 let item_index = self.item_refs.get(&value[..]).cloned();
158
159 if let Some(item_index) = item_index {
54a0048b
SL
160 self.collect_item(item_index, self.ast_map.local_def_id(item.id))
161 } else {
162 let span = self.ast_map.span(item.id);
163 span_err!(self.session, span, E0522,
164 "definition of an unknown language item: `{}`.",
165 &value[..]);
1a4d82fc 166 }
1a4d82fc 167 }
1a4d82fc
JJ
168 }
169}
170
b039eaaf
SL
171impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> {
172 pub fn new(session: &'a Session, ast_map: &'a hir_map::Map<'tcx>)
173 -> LanguageItemCollector<'a, 'tcx> {
85aaf69f 174 let mut item_refs = FnvHashMap();
1a4d82fc 175
c34b1796 176 $( item_refs.insert($name, $variant as usize); )*
970d7e83
LB
177
178 LanguageItemCollector {
970d7e83 179 session: session,
b039eaaf 180 ast_map: ast_map,
970d7e83 181 items: LanguageItems::new(),
b039eaaf 182 item_refs: item_refs,
970d7e83
LB
183 }
184 }
185
c34b1796 186 pub fn collect_item(&mut self, item_index: usize,
54a0048b 187 item_def_id: DefId) {
223e47cc
LB
188 // Check for duplicates.
189 match self.items.items[item_index] {
190 Some(original_def_id) if original_def_id != item_def_id => {
7453a54e 191 let cstore = &self.session.cstore;
54a0048b
SL
192 let span = self.ast_map.span_if_local(item_def_id)
193 .expect("we should have found local duplicate earlier");
194 let mut err = struct_span_err!(self.session,
195 span,
196 E0152,
197 "duplicate lang item found: `{}`.",
198 LanguageItems::item_name(item_index));
199 if let Some(span) = self.ast_map.span_if_local(original_def_id) {
200 span_note!(&mut err, span,
201 "first defined here.");
202 } else {
203 err.note(&format!("first defined in crate `{}`.",
204 cstore.crate_name(original_def_id.krate)));
205 }
206 err.emit();
223e47cc 207 }
7453a54e 208 _ => {
223e47cc
LB
209 // OK.
210 }
211 }
212
213 // Matched.
214 self.items.items[item_index] = Some(item_def_id);
215 }
216
e9174d1e 217 pub fn collect_local_language_items(&mut self, krate: &hir::Crate) {
92a42be0 218 krate.visit_all_items(self);
223e47cc
LB
219 }
220
970d7e83 221 pub fn collect_external_language_items(&mut self) {
92a42be0 222 let cstore = &self.session.cstore;
54a0048b 223
92a42be0
SL
224 for cnum in cstore.crates() {
225 for (index, item_index) in cstore.lang_items(cnum) {
226 let def_id = DefId { krate: cnum, index: index };
54a0048b 227 self.collect_item(item_index, def_id);
92a42be0
SL
228 }
229 }
1a4d82fc
JJ
230 }
231
e9174d1e 232 pub fn collect(&mut self, krate: &hir::Crate) {
1a4d82fc 233 self.collect_external_language_items();
54a0048b 234 self.collect_local_language_items(krate);
223e47cc 235 }
1a4d82fc 236}
223e47cc 237
b039eaaf 238pub fn extract(attrs: &[ast::Attribute]) -> Option<InternedString> {
85aaf69f 239 for attribute in attrs {
1a4d82fc
JJ
240 match attribute.value_str() {
241 Some(ref value) if attribute.check_name("lang") => {
242 return Some(value.clone());
223e47cc 243 }
1a4d82fc 244 _ => {}
223e47cc
LB
245 }
246 }
247
1a4d82fc 248 return None;
223e47cc
LB
249}
250
b039eaaf
SL
251pub fn collect_language_items(session: &Session,
252 map: &hir_map::Map)
253 -> LanguageItems {
7453a54e 254 let _task = map.dep_graph.in_task(DepNode::CollectLanguageItems);
b039eaaf
SL
255 let krate: &hir::Crate = map.krate();
256 let mut collector = LanguageItemCollector::new(session, map);
1a4d82fc
JJ
257 collector.collect(krate);
258 let LanguageItemCollector { mut items, .. } = collector;
259 weak_lang_items::check_crate(krate, session, &mut items);
970d7e83 260 items
223e47cc 261}
1a4d82fc
JJ
262
263// End of the macro
264 }
265}
266
267lets_do_this! {
268// Variant name, Name, Method name;
c34b1796
AL
269 CharImplItem, "char", char_impl;
270 StrImplItem, "str", str_impl;
271 SliceImplItem, "slice", slice_impl;
272 ConstPtrImplItem, "const_ptr", const_ptr_impl;
273 MutPtrImplItem, "mut_ptr", mut_ptr_impl;
274 I8ImplItem, "i8", i8_impl;
275 I16ImplItem, "i16", i16_impl;
276 I32ImplItem, "i32", i32_impl;
277 I64ImplItem, "i64", i64_impl;
278 IsizeImplItem, "isize", isize_impl;
279 U8ImplItem, "u8", u8_impl;
280 U16ImplItem, "u16", u16_impl;
281 U32ImplItem, "u32", u32_impl;
282 U64ImplItem, "u64", u64_impl;
283 UsizeImplItem, "usize", usize_impl;
284 F32ImplItem, "f32", f32_impl;
285 F64ImplItem, "f64", f64_impl;
286
1a4d82fc
JJ
287 SendTraitLangItem, "send", send_trait;
288 SizedTraitLangItem, "sized", sized_trait;
d9579d0f 289 UnsizeTraitLangItem, "unsize", unsize_trait;
1a4d82fc
JJ
290 CopyTraitLangItem, "copy", copy_trait;
291 SyncTraitLangItem, "sync", sync_trait;
292
293 DropTraitLangItem, "drop", drop_trait;
294
d9579d0f
AL
295 CoerceUnsizedTraitLangItem, "coerce_unsized", coerce_unsized_trait;
296
1a4d82fc
JJ
297 AddTraitLangItem, "add", add_trait;
298 SubTraitLangItem, "sub", sub_trait;
299 MulTraitLangItem, "mul", mul_trait;
300 DivTraitLangItem, "div", div_trait;
301 RemTraitLangItem, "rem", rem_trait;
302 NegTraitLangItem, "neg", neg_trait;
303 NotTraitLangItem, "not", not_trait;
304 BitXorTraitLangItem, "bitxor", bitxor_trait;
305 BitAndTraitLangItem, "bitand", bitand_trait;
306 BitOrTraitLangItem, "bitor", bitor_trait;
307 ShlTraitLangItem, "shl", shl_trait;
308 ShrTraitLangItem, "shr", shr_trait;
b039eaaf
SL
309 AddAssignTraitLangItem, "add_assign", add_assign_trait;
310 SubAssignTraitLangItem, "sub_assign", sub_assign_trait;
311 MulAssignTraitLangItem, "mul_assign", mul_assign_trait;
312 DivAssignTraitLangItem, "div_assign", div_assign_trait;
313 RemAssignTraitLangItem, "rem_assign", rem_assign_trait;
314 BitXorAssignTraitLangItem, "bitxor_assign", bitxor_assign_trait;
315 BitAndAssignTraitLangItem, "bitand_assign", bitand_assign_trait;
316 BitOrAssignTraitLangItem, "bitor_assign", bitor_assign_trait;
317 ShlAssignTraitLangItem, "shl_assign", shl_assign_trait;
318 ShrAssignTraitLangItem, "shr_assign", shr_assign_trait;
1a4d82fc
JJ
319 IndexTraitLangItem, "index", index_trait;
320 IndexMutTraitLangItem, "index_mut", index_mut_trait;
1a4d82fc 321
85aaf69f 322 UnsafeCellTypeLangItem, "unsafe_cell", unsafe_cell_type;
1a4d82fc
JJ
323
324 DerefTraitLangItem, "deref", deref_trait;
325 DerefMutTraitLangItem, "deref_mut", deref_mut_trait;
326
327 FnTraitLangItem, "fn", fn_trait;
328 FnMutTraitLangItem, "fn_mut", fn_mut_trait;
329 FnOnceTraitLangItem, "fn_once", fn_once_trait;
330
331 EqTraitLangItem, "eq", eq_trait;
332 OrdTraitLangItem, "ord", ord_trait;
333
334 StrEqFnLangItem, "str_eq", str_eq_fn;
335
336 // A number of panic-related lang items. The `panic` item corresponds to
337 // divide-by-zero and various panic cases with `match`. The
338 // `panic_bounds_check` item is for indexing arrays.
339 //
340 // The `begin_unwind` lang item has a predefined symbol name and is sort of
341 // a "weak lang item" in the sense that a crate is not required to have it
342 // defined to use it, but a final product is required to define it
343 // somewhere. Additionally, there are restrictions on crates that use a weak
344 // lang item, but do not have it defined.
345 PanicFnLangItem, "panic", panic_fn;
346 PanicBoundsCheckFnLangItem, "panic_bounds_check", panic_bounds_check_fn;
347 PanicFmtLangItem, "panic_fmt", panic_fmt;
348
349 ExchangeMallocFnLangItem, "exchange_malloc", exchange_malloc_fn;
350 ExchangeFreeFnLangItem, "exchange_free", exchange_free_fn;
7453a54e 351 BoxFreeFnLangItem, "box_free", box_free_fn;
1a4d82fc
JJ
352 StrDupUniqFnLangItem, "strdup_uniq", strdup_uniq_fn;
353
354 StartFnLangItem, "start", start_fn;
355
1a4d82fc 356 EhPersonalityLangItem, "eh_personality", eh_personality;
c1a9b12d
SL
357 EhPersonalityCatchLangItem, "eh_personality_catch", eh_personality_catch;
358 EhUnwindResumeLangItem, "eh_unwind_resume", eh_unwind_resume;
359 MSVCTryFilterLangItem, "msvc_try_filter", msvc_try_filter;
1a4d82fc 360
1a4d82fc
JJ
361 OwnedBoxLangItem, "owned_box", owned_box;
362
85aaf69f
SL
363 PhantomDataItem, "phantom_data", phantom_data;
364
365 // Deprecated:
1a4d82fc
JJ
366 CovariantTypeItem, "covariant_type", covariant_type;
367 ContravariantTypeItem, "contravariant_type", contravariant_type;
368 InvariantTypeItem, "invariant_type", invariant_type;
1a4d82fc
JJ
369 CovariantLifetimeItem, "covariant_lifetime", covariant_lifetime;
370 ContravariantLifetimeItem, "contravariant_lifetime", contravariant_lifetime;
371 InvariantLifetimeItem, "invariant_lifetime", invariant_lifetime;
372
1a4d82fc 373 NoCopyItem, "no_copy_bound", no_copy_bound;
1a4d82fc
JJ
374
375 NonZeroItem, "non_zero", non_zero;
376
85aaf69f 377 DebugTraitLangItem, "debug_trait", debug_trait;
1a4d82fc 378}