]> git.proxmox.com Git - rustc.git/blame - src/doc/unstable-book/src/language-features/lang-items.md
New upstream version 1.23.0+dfsg1
[rustc.git] / src / doc / unstable-book / src / language-features / lang-items.md
CommitLineData
8bb4bdeb 1# `lang_items`
92a42be0 2
8bb4bdeb 3The tracking issue for this feature is: None.
92a42be0 4
8bb4bdeb 5------------------------
92a42be0 6
8bb4bdeb
XL
7The `rustc` compiler has certain pluggable operations, that is,
8functionality that isn't hard-coded into the language, but is
9implemented in libraries, with a special marker to tell the compiler
10it exists. The marker is the attribute `#[lang = "..."]` and there are
11various different values of `...`, i.e. various different 'lang
12items'.
13
14For example, `Box` pointers require two lang items, one for allocation
15and one for deallocation. A freestanding program that uses the `Box`
16sugar for dynamic allocations via `malloc` and `free`:
17
18```rust,ignore
19#![feature(lang_items, box_syntax, start, libc, core_intrinsics)]
20#![no_std]
21use core::intrinsics;
22
23extern crate libc;
24
25#[lang = "owned_box"]
26pub struct Box<T>(*mut T);
27
28#[lang = "exchange_malloc"]
29unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
30 let p = libc::malloc(size as libc::size_t) as *mut u8;
31
32 // Check if `malloc` failed:
33 if p as usize == 0 {
34 intrinsics::abort();
35 }
36
37 p
38}
39
40#[lang = "exchange_free"]
41unsafe fn deallocate(ptr: *mut u8, _size: usize, _align: usize) {
42 libc::free(ptr as *mut libc::c_void)
43}
44
45#[lang = "box_free"]
46unsafe fn box_free<T: ?Sized>(ptr: *mut T) {
47 deallocate(ptr as *mut u8, ::core::mem::size_of_val(&*ptr), ::core::mem::align_of_val(&*ptr));
48}
49
50#[start]
51fn main(argc: isize, argv: *const *const u8) -> isize {
52 let x = box 1;
53
54 0
55}
56
57#[lang = "eh_personality"] extern fn rust_eh_personality() {}
58#[lang = "panic_fmt"] extern fn rust_begin_panic() -> ! { unsafe { intrinsics::abort() } }
59# #[lang = "eh_unwind_resume"] extern fn rust_eh_unwind_resume() {}
60# #[no_mangle] pub extern fn rust_eh_register_frames () {}
61# #[no_mangle] pub extern fn rust_eh_unregister_frames () {}
62```
63
64Note the use of `abort`: the `exchange_malloc` lang item is assumed to
65return a valid pointer, and so needs to do the check internally.
66
67Other features provided by lang items include:
68
69- overloadable operators via traits: the traits corresponding to the
70 `==`, `<`, dereferencing (`*`) and `+` (etc.) operators are all
71 marked with lang items; those specific four are `eq`, `ord`,
72 `deref`, and `add` respectively.
73- stack unwinding and general failure; the `eh_personality`,
74 `eh_unwind_resume`, `fail` and `fail_bounds_checks` lang items.
75- the traits in `std::marker` used to indicate types of
76 various kinds; lang items `send`, `sync` and `copy`.
77- the marker types and variance indicators found in
78 `std::marker`; lang items `covariant_type`,
79 `contravariant_lifetime`, etc.
80
81Lang items are loaded lazily by the compiler; e.g. if one never uses
82`Box` then there is no need to define functions for `exchange_malloc`
83and `exchange_free`. `rustc` will emit an error when an item is needed
84but not found in the current crate or any that it depends on.
85
86Most lang items are defined by `libcore`, but if you're trying to build
87an executable without the standard library, you'll run into the need
88for lang items. The rest of this page focuses on this use-case, even though
89lang items are a bit broader than that.
3157f602
XL
90
91### Using libc
92
8bb4bdeb
XL
93In order to build a `#[no_std]` executable we will need libc as a dependency.
94We can specify this using our `Cargo.toml` file:
3157f602
XL
95
96```toml
97[dependencies]
5bcae85e 98libc = { version = "0.2.14", default-features = false }
3157f602
XL
99```
100
101Note that the default features have been disabled. This is a critical step -
102**the default features of libc include the standard library and so must be
103disabled.**
104
105### Writing an executable without stdlib
106
107Controlling the entry point is possible in two ways: the `#[start]` attribute,
108or overriding the default shim for the C `main` function with your own.
92a42be0
SL
109
110The function marked `#[start]` is passed the command line parameters
111in the same format as C:
112
5bcae85e 113```rust,ignore
32a655c1 114#![feature(lang_items, core_intrinsics)]
92a42be0
SL
115#![feature(start)]
116#![no_std]
32a655c1 117use core::intrinsics;
92a42be0 118
476ff2be 119// Pull in the system libc library for what crt0.o likely requires.
92a42be0
SL
120extern crate libc;
121
476ff2be 122// Entry point for this program.
92a42be0
SL
123#[start]
124fn start(_argc: isize, _argv: *const *const u8) -> isize {
125 0
126}
127
5bcae85e 128// These functions are used by the compiler, but not
92a42be0
SL
129// for a bare-bones hello world. These are normally
130// provided by libstd.
5bcae85e
SL
131#[lang = "eh_personality"]
132#[no_mangle]
9e0c209e
SL
133pub extern fn rust_eh_personality() {
134}
135
136// This function may be needed based on the compilation target.
137#[lang = "eh_unwind_resume"]
138#[no_mangle]
139pub extern fn rust_eh_unwind_resume() {
5bcae85e
SL
140}
141
142#[lang = "panic_fmt"]
143#[no_mangle]
144pub extern fn rust_begin_panic(_msg: core::fmt::Arguments,
145 _file: &'static str,
041b39d2
XL
146 _line: u32,
147 _column: u32) -> ! {
32a655c1 148 unsafe { intrinsics::abort() }
5bcae85e 149}
92a42be0
SL
150```
151
152To override the compiler-inserted `main` shim, one has to disable it
153with `#![no_main]` and then create the appropriate symbol with the
154correct ABI and the correct name, which requires overriding the
155compiler's name mangling too:
156
5bcae85e 157```rust,ignore
32a655c1 158#![feature(lang_items, core_intrinsics)]
92a42be0
SL
159#![feature(start)]
160#![no_std]
161#![no_main]
32a655c1 162use core::intrinsics;
92a42be0 163
476ff2be 164// Pull in the system libc library for what crt0.o likely requires.
92a42be0
SL
165extern crate libc;
166
476ff2be 167// Entry point for this program.
92a42be0 168#[no_mangle] // ensure that this symbol is called `main` in the output
5bcae85e 169pub extern fn main(_argc: i32, _argv: *const *const u8) -> i32 {
92a42be0
SL
170 0
171}
172
9e0c209e 173// These functions are used by the compiler, but not
5bcae85e
SL
174// for a bare-bones hello world. These are normally
175// provided by libstd.
176#[lang = "eh_personality"]
177#[no_mangle]
9e0c209e
SL
178pub extern fn rust_eh_personality() {
179}
180
181// This function may be needed based on the compilation target.
182#[lang = "eh_unwind_resume"]
183#[no_mangle]
184pub extern fn rust_eh_unwind_resume() {
5bcae85e
SL
185}
186
187#[lang = "panic_fmt"]
188#[no_mangle]
189pub extern fn rust_begin_panic(_msg: core::fmt::Arguments,
190 _file: &'static str,
041b39d2
XL
191 _line: u32,
192 _column: u32) -> ! {
32a655c1 193 unsafe { intrinsics::abort() }
5bcae85e 194}
92a42be0
SL
195```
196
3b2f2976
XL
197In many cases, you may need to manually link to the `compiler_builtins` crate
198when building a `no_std` binary. You may observe this via linker error messages
199such as "```undefined reference to `__rust_probestack'```". Using this crate
200also requires enabling the library feature `compiler_builtins_lib`. You can read
201more about this [here][compiler-builtins-lib].
202
203[compiler-builtins-lib]: library-features/compiler-builtins-lib.html
204
9e0c209e 205## More about the language items
5bcae85e
SL
206
207The compiler currently makes a few assumptions about symbols which are
208available in the executable to call. Normally these functions are provided by
209the standard library, but without it you must define your own. These symbols
210are called "language items", and they each have an internal name, and then a
211signature that an implementation must conform to.
92a42be0 212
9e0c209e 213The first of these functions, `rust_eh_personality`, is used by the failure
7453a54e
SL
214mechanisms of the compiler. This is often mapped to GCC's personality function
215(see the [libstd implementation][unwind] for more information), but crates
216which do not trigger a panic can be assured that this function is never
9e0c209e
SL
217called. The language item's name is `eh_personality`.
218
3157f602 219[unwind]: https://github.com/rust-lang/rust/blob/master/src/libpanic_unwind/gcc.rs
5bcae85e 220
9e0c209e 221The second function, `rust_begin_panic`, is also used by the failure mechanisms of the
5bcae85e
SL
222compiler. When a panic happens, this controls the message that's displayed on
223the screen. While the language item's name is `panic_fmt`, the symbol name is
224`rust_begin_panic`.
9e0c209e
SL
225
226A third function, `rust_eh_unwind_resume`, is also needed if the `custom_unwind_resume`
227flag is set in the options of the compilation target. It allows customizing the
228process of resuming unwind at the end of the landing pads. The language item's name
229is `eh_unwind_resume`.
abe05a73
XL
230
231## List of all language items
232
233This is a list of all language items in Rust along with where they are located in
234the source code.
235
236- Primitives
237 - `i8`: `libcore/num/mod.rs`
238 - `i16`: `libcore/num/mod.rs`
239 - `i32`: `libcore/num/mod.rs`
240 - `i64`: `libcore/num/mod.rs`
241 - `i128`: `libcore/num/mod.rs`
242 - `isize`: `libcore/num/mod.rs`
243 - `u8`: `libcore/num/mod.rs`
244 - `u16`: `libcore/num/mod.rs`
245 - `u32`: `libcore/num/mod.rs`
246 - `u64`: `libcore/num/mod.rs`
247 - `u128`: `libcore/num/mod.rs`
248 - `usize`: `libcore/num/mod.rs`
249 - `f32`: `libstd/f32.rs`
250 - `f64`: `libstd/f64.rs`
251 - `char`: `libstd_unicode/char.rs`
252 - `slice`: `liballoc/slice.rs`
253 - `str`: `liballoc/str.rs`
254 - `const_ptr`: `libcore/ptr.rs`
255 - `mut_ptr`: `libcore/ptr.rs`
256 - `unsafe_cell`: `libcore/cell.rs`
257- Runtime
258 - `start`: `libstd/rt.rs`
259 - `eh_personality`: `libpanic_unwind/emcc.rs` (EMCC)
260 - `eh_personality`: `libpanic_unwind/seh64_gnu.rs` (SEH64 GNU)
261 - `eh_personality`: `libpanic_unwind/seh.rs` (SEH)
262 - `eh_unwind_resume`: `libpanic_unwind/seh64_gnu.rs` (SEH64 GNU)
263 - `eh_unwind_resume`: `libpanic_unwind/gcc.rs` (GCC)
264 - `msvc_try_filter`: `libpanic_unwind/seh.rs` (SEH)
265 - `panic`: `libcore/panicking.rs`
266 - `panic_bounds_check`: `libcore/panicking.rs`
267 - `panic_fmt`: `libcore/panicking.rs`
268 - `panic_fmt`: `libstd/panicking.rs`
269- Allocations
270 - `owned_box`: `liballoc/boxed.rs`
271 - `exchange_malloc`: `liballoc/heap.rs`
272 - `box_free`: `liballoc/heap.rs`
273- Operands
274 - `not`: `libcore/ops/bit.rs`
275 - `bitand`: `libcore/ops/bit.rs`
276 - `bitor`: `libcore/ops/bit.rs`
277 - `bitxor`: `libcore/ops/bit.rs`
278 - `shl`: `libcore/ops/bit.rs`
279 - `shr`: `libcore/ops/bit.rs`
280 - `bitand_assign`: `libcore/ops/bit.rs`
281 - `bitor_assign`: `libcore/ops/bit.rs`
282 - `bitxor_assign`: `libcore/ops/bit.rs`
283 - `shl_assign`: `libcore/ops/bit.rs`
284 - `shr_assign`: `libcore/ops/bit.rs`
285 - `deref`: `libcore/ops/deref.rs`
286 - `deref_mut`: `libcore/ops/deref.rs`
287 - `index`: `libcore/ops/index.rs`
288 - `index_mut`: `libcore/ops/index.rs`
289 - `add`: `libcore/ops/arith.rs`
290 - `sub`: `libcore/ops/arith.rs`
291 - `mul`: `libcore/ops/arith.rs`
292 - `div`: `libcore/ops/arith.rs`
293 - `rem`: `libcore/ops/arith.rs`
294 - `neg`: `libcore/ops/arith.rs`
295 - `add_assign`: `libcore/ops/arith.rs`
296 - `sub_assign`: `libcore/ops/arith.rs`
297 - `mul_assign`: `libcore/ops/arith.rs`
298 - `div_assign`: `libcore/ops/arith.rs`
299 - `rem_assign`: `libcore/ops/arith.rs`
300 - `eq`: `libcore/cmp.rs`
301 - `ord`: `libcore/cmp.rs`
302- Functions
303 - `fn`: `libcore/ops/function.rs`
304 - `fn_mut`: `libcore/ops/function.rs`
305 - `fn_once`: `libcore/ops/function.rs`
306 - `generator_state`: `libcore/ops/generator.rs`
307 - `generator`: `libcore/ops/generator.rs`
308- Other
309 - `coerce_unsized`: `libcore/ops/unsize.rs`
310 - `drop`: `libcore/ops/drop.rs`
311 - `drop_in_place`: `libcore/ptr.rs`
312 - `clone`: `libcore/clone.rs`
313 - `copy`: `libcore/marker.rs`
314 - `send`: `libcore/marker.rs`
315 - `sized`: `libcore/marker.rs`
316 - `unsize`: `libcore/marker.rs`
317 - `sync`: `libcore/marker.rs`
318 - `phantom_data`: `libcore/marker.rs`
319 - `freeze`: `libcore/marker.rs`
320 - `debug_trait`: `libcore/fmt/mod.rs`
321 - `non_zero`: `libcore/nonzero.rs`