]>
Commit | Line | Data |
---|---|---|
c34b1796 AL |
1 | % Lang items |
2 | ||
3 | > **Note**: lang items are often provided by crates in the Rust distribution, | |
4 | > and lang items themselves have an unstable interface. It is recommended to use | |
5 | > officially distributed crates instead of defining your own lang items. | |
6 | ||
7 | The `rustc` compiler has certain pluggable operations, that is, | |
8 | functionality that isn't hard-coded into the language, but is | |
9 | implemented in libraries, with a special marker to tell the compiler | |
bd371182 | 10 | it exists. The marker is the attribute `#[lang = "..."]` and there are |
c34b1796 AL |
11 | various different values of `...`, i.e. various different 'lang |
12 | items'. | |
13 | ||
14 | For example, `Box` pointers require two lang items, one for allocation | |
15 | and one for deallocation. A freestanding program that uses the `Box` | |
16 | sugar for dynamic allocations via `malloc` and `free`: | |
17 | ||
5bcae85e | 18 | ```rust,ignore |
92a42be0 | 19 | #![feature(lang_items, box_syntax, start, libc)] |
c34b1796 AL |
20 | #![no_std] |
21 | ||
22 | extern crate libc; | |
23 | ||
24 | extern { | |
25 | fn abort() -> !; | |
26 | } | |
27 | ||
28 | #[lang = "owned_box"] | |
29 | pub struct Box<T>(*mut T); | |
30 | ||
bd371182 | 31 | #[lang = "exchange_malloc"] |
c34b1796 AL |
32 | unsafe fn allocate(size: usize, _align: usize) -> *mut u8 { |
33 | let p = libc::malloc(size as libc::size_t) as *mut u8; | |
34 | ||
35 | // malloc failed | |
36 | if p as usize == 0 { | |
37 | abort(); | |
38 | } | |
39 | ||
40 | p | |
41 | } | |
7453a54e | 42 | |
bd371182 | 43 | #[lang = "exchange_free"] |
c34b1796 AL |
44 | unsafe fn deallocate(ptr: *mut u8, _size: usize, _align: usize) { |
45 | libc::free(ptr as *mut libc::c_void) | |
46 | } | |
47 | ||
7453a54e SL |
48 | #[lang = "box_free"] |
49 | unsafe fn box_free<T>(ptr: *mut T) { | |
50 | deallocate(ptr as *mut u8, ::core::mem::size_of::<T>(), ::core::mem::align_of::<T>()); | |
51 | } | |
52 | ||
c34b1796 AL |
53 | #[start] |
54 | fn main(argc: isize, argv: *const *const u8) -> isize { | |
55 | let x = box 1; | |
56 | ||
57 | 0 | |
58 | } | |
59 | ||
9e0c209e SL |
60 | #[lang = "eh_personality"] extern fn rust_eh_personality() {} |
61 | #[lang = "panic_fmt"] extern fn rust_begin_panic() -> ! { loop {} } | |
c1a9b12d | 62 | # #[lang = "eh_unwind_resume"] extern fn rust_eh_unwind_resume() {} |
92a42be0 SL |
63 | # #[no_mangle] pub extern fn rust_eh_register_frames () {} |
64 | # #[no_mangle] pub extern fn rust_eh_unregister_frames () {} | |
c34b1796 AL |
65 | ``` |
66 | ||
67 | Note the use of `abort`: the `exchange_malloc` lang item is assumed to | |
68 | return a valid pointer, and so needs to do the check internally. | |
69 | ||
70 | Other features provided by lang items include: | |
71 | ||
72 | - overloadable operators via traits: the traits corresponding to the | |
73 | `==`, `<`, dereferencing (`*`) and `+` (etc.) operators are all | |
74 | marked with lang items; those specific four are `eq`, `ord`, | |
75 | `deref`, and `add` respectively. | |
9e0c209e SL |
76 | - stack unwinding and general failure; the `eh_personality`, |
77 | `eh_unwind_resume`, `fail` and `fail_bounds_checks` lang items. | |
c34b1796 AL |
78 | - the traits in `std::marker` used to indicate types of |
79 | various kinds; lang items `send`, `sync` and `copy`. | |
80 | - the marker types and variance indicators found in | |
81 | `std::marker`; lang items `covariant_type`, | |
82 | `contravariant_lifetime`, etc. | |
83 | ||
84 | Lang items are loaded lazily by the compiler; e.g. if one never uses | |
85 | `Box` then there is no need to define functions for `exchange_malloc` | |
86 | and `exchange_free`. `rustc` will emit an error when an item is needed | |
87 | but not found in the current crate or any that it depends on. |