@@ -9,26 +9,60 @@ functionality that isn't hard-coded into the language, but is
99implemented in libraries, with a special marker to tell the compiler
1010it exists. The marker is the attribute ` #[lang = "..."] ` and there are
1111various different values of ` ... ` , i.e. various different 'lang
12- items'.
12+ items'. Most of them can only be defined once.
1313
14- For example, ` Box ` pointers require a lang item for allocation.
15- A freestanding program that uses the ` Box `
16- sugar for dynamic allocations via ` malloc ` and ` free ` :
14+ Lang items are loaded lazily by the compiler; e.g. if one never uses ` Box `
15+ then there is no need to define a function for ` exchange_malloc ` .
16+ ` rustc ` will emit an error when an item is needed but not found in the current
17+ crate or any that it depends on.
18+
19+ Some features provided by lang items:
20+
21+ - overloadable operators via traits: the traits corresponding to the
22+ ` == ` , ` < ` , dereferencing (` * ` ) and ` + ` (etc.) operators are all
23+ marked with lang items; those specific four are ` eq ` , ` partial_ord ` ,
24+ ` deref ` /` deref_mut ` , and ` add ` respectively.
25+ - panicking: the ` panic ` and ` panic_impl ` lang items, among others.
26+ - stack unwinding: the lang item ` eh_personality ` is a function used by the
27+ failure mechanisms of the compiler. This is often mapped to GCC's personality
28+ function (see the [ ` std ` implementation] [ personality ] for more information),
29+ but programs which don't trigger a panic can be assured that this function is
30+ never called. Additionally, a ` eh_catch_typeinfo ` static is needed for certain
31+ targets which implement Rust panics on top of C++ exceptions.
32+ - the traits in ` core::marker ` used to indicate types of
33+ various kinds; e.g. lang items ` sized ` , ` sync ` and ` copy ` .
34+ - memory allocation, see below.
35+
36+ Most lang items are defined by ` core ` , but if you're trying to build
37+ an executable without the ` std ` crate, you might run into the need
38+ for lang item definitions.
39+
40+ [ personality ] : https://github.com/rust-lang/rust/blob/master/library/std/src/personality/gcc.rs
41+
42+ ## Example: Implementing a ` Box `
43+
44+ ` Box ` pointers require two lang items: one for the type itself and one for
45+ allocation. A freestanding program that uses the ` Box ` sugar for dynamic
46+ allocations via ` malloc ` and ` free ` :
1747
1848``` rust,ignore (libc-is-finicky)
19- #![feature(lang_items, start, libc, core_intrinsics, rustc_private, rustc_attrs)]
49+ #![feature(lang_items, start, core_intrinsics, rustc_private, panic_unwind , rustc_attrs)]
2050#![allow(internal_features)]
2151#![no_std]
52+
53+ extern crate libc;
54+ extern crate unwind;
55+
56+ use core::ffi::c_void;
2257use core::intrinsics;
2358use core::panic::PanicInfo;
2459use core::ptr::NonNull;
2560
26- extern crate libc;
27-
61+ pub struct Global; // the global allocator
2862struct Unique<T>(NonNull<T>);
2963
3064#[lang = "owned_box"]
31- pub struct Box<T>(Unique<T>);
65+ pub struct Box<T, A = Global >(Unique<T>, A );
3266
3367impl<T> Box<T> {
3468 pub fn new(x: T) -> Self {
@@ -37,272 +71,45 @@ impl<T> Box<T> {
3771 }
3872}
3973
74+ impl<T, A> Drop for Box<T, A> {
75+ fn drop(&mut self) {
76+ unsafe {
77+ libc::free(self.0.0.as_ptr() as *mut c_void);
78+ }
79+ }
80+ }
81+
4082#[lang = "exchange_malloc"]
4183unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
42- let p = libc::malloc(size as libc::size_t ) as *mut u8;
84+ let p = libc::malloc(size) as *mut u8;
4385
4486 // Check if `malloc` failed:
45- if p as usize == 0 {
87+ if p.is_null() {
4688 intrinsics::abort();
4789 }
4890
4991 p
5092}
5193
52- impl<T> Drop for Box<T> {
53- fn drop(&mut self) {
54- libc::free(self.0.0.0 as *mut libc::c_void)
55- }
56- }
57-
5894#[start]
5995fn main(_argc: isize, _argv: *const *const u8) -> isize {
6096 let _x = Box::new(1);
6197
6298 0
6399}
64100
65- #[lang = "eh_personality"] extern fn rust_eh_personality() {}
66- #[lang = "panic_impl"] extern fn rust_begin_panic(_info: &PanicInfo) -> ! { intrinsics::abort() }
67- #[no_mangle] pub extern fn rust_eh_register_frames () {}
68- #[no_mangle] pub extern fn rust_eh_unregister_frames () {}
69- ```
70-
71- Note the use of ` abort ` : the ` exchange_malloc ` lang item is assumed to
72- return a valid pointer, and so needs to do the check internally.
73-
74- Other features provided by lang items include:
75-
76- - overloadable operators via traits: the traits corresponding to the
77- ` == ` , ` < ` , dereferencing (` * ` ) and ` + ` (etc.) operators are all
78- marked with lang items; those specific four are ` eq ` , ` ord ` ,
79- ` deref ` , and ` add ` respectively.
80- - stack unwinding and general failure; the ` eh_personality ` ,
81- ` panic ` and ` panic_bounds_check ` lang items.
82- - the traits in ` std::marker ` used to indicate types of
83- various kinds; lang items ` send ` , ` sync ` and ` copy ` .
84- - the marker types and variance indicators found in
85- ` std::marker ` ; lang items ` covariant_type ` ,
86- ` contravariant_lifetime ` , etc.
87-
88- Lang items are loaded lazily by the compiler; e.g. if one never uses
89- ` Box ` then there is no need to define a function for ` exchange_malloc ` .
90- ` rustc ` will emit an error when an item is needed
91- but not found in the current crate or any that it depends on.
92-
93- Most lang items are defined by ` libcore ` , but if you're trying to build
94- an executable without the standard library, you'll run into the need
95- for lang items. The rest of this page focuses on this use-case, even though
96- lang items are a bit broader than that.
97-
98- ### Using libc
99-
100- In order to build a ` #[no_std] ` executable we will need libc as a dependency.
101- We can specify this using our ` Cargo.toml ` file:
102-
103- ``` toml
104- [dependencies ]
105- libc = { version = " 0.2.14" , default-features = false }
106- ```
107-
108- Note that the default features have been disabled. This is a critical step -
109- ** the default features of libc include the standard library and so must be
110- disabled.**
111-
112- ### Writing an executable without stdlib
113-
114- Controlling the entry point is possible in two ways: the ` #[start] ` attribute,
115- or overriding the default shim for the C ` main ` function with your own.
116-
117- The function marked ` #[start] ` is passed the command line parameters
118- in the same format as C:
119-
120- ``` rust,ignore (libc-is-finicky)
121- #![feature(lang_items, core_intrinsics, rustc_private)]
122- #![feature(start)]
123- #![allow(internal_features)]
124- #![no_std]
125- use core::intrinsics;
126- use core::panic::PanicInfo;
127-
128- // Pull in the system libc library for what crt0.o likely requires.
129- extern crate libc;
130-
131- // Entry point for this program.
132- #[start]
133- fn start(_argc: isize, _argv: *const *const u8) -> isize {
134- 0
135- }
136-
137- // These functions are used by the compiler, but not
138- // for a bare-bones hello world. These are normally
139- // provided by libstd.
140- #[lang = "eh_personality"]
141- #[no_mangle]
142- pub extern fn rust_eh_personality() {
143- }
144-
145- #[lang = "panic_impl"]
146- #[no_mangle]
147- pub extern fn rust_begin_panic(info: &PanicInfo) -> ! {
148- unsafe { intrinsics::abort() }
149- }
150- ```
151-
152- To override the compiler-inserted ` main ` shim, one has to disable it
153- with ` #![no_main] ` and then create the appropriate symbol with the
154- correct ABI and the correct name, which requires overriding the
155- compiler's name mangling too:
156-
157- ``` rust,ignore (libc-is-finicky)
158- #![feature(lang_items, core_intrinsics, rustc_private)]
159- #![feature(start)]
160- #![allow(internal_features)]
161- #![no_std]
162- #![no_main]
163- use core::intrinsics;
164- use core::panic::PanicInfo;
165-
166- // Pull in the system libc library for what crt0.o likely requires.
167- extern crate libc;
168-
169- // Entry point for this program.
170- #[no_mangle] // ensure that this symbol is called `main` in the output
171- pub extern fn main(_argc: i32, _argv: *const *const u8) -> i32 {
172- 0
173- }
174-
175- // These functions are used by the compiler, but not
176- // for a bare-bones hello world. These are normally
177- // provided by libstd.
178101#[lang = "eh_personality"]
179- #[no_mangle]
180- pub extern fn rust_eh_personality() {
181- }
102+ fn rust_eh_personality() {}
182103
183- #[lang = "panic_impl"]
184- #[no_mangle]
185- pub extern fn rust_begin_panic(info: &PanicInfo) -> ! {
186- unsafe { intrinsics::abort() }
187- }
104+ #[panic_handler]
105+ fn panic_handler(_info: &PanicInfo) -> ! { intrinsics::abort() }
188106```
189107
190- In many cases, you may need to manually link to the ` compiler_builtins ` crate
191- when building a ` no_std ` binary. You may observe this via linker error messages
192- such as "``` undefined reference to `__rust_probestack' ``` ".
193-
194- ## More about the language items
195-
196- The compiler currently makes a few assumptions about symbols which are
197- available in the executable to call. Normally these functions are provided by
198- the standard library, but without it you must define your own. These symbols
199- are called "language items", and they each have an internal name, and then a
200- signature that an implementation must conform to.
201-
202- The first of these functions, ` rust_eh_personality ` , is used by the failure
203- mechanisms of the compiler. This is often mapped to GCC's personality function
204- (see the [ libstd implementation] [ unwind ] for more information), but crates
205- which do not trigger a panic can be assured that this function is never
206- called. The language item's name is ` eh_personality ` .
207-
208- [ unwind ] : https://github.com/rust-lang/rust/blob/master/library/panic_unwind/src/gcc.rs
209-
210- The second function, ` rust_begin_panic ` , is also used by the failure mechanisms of the
211- compiler. When a panic happens, this controls the message that's displayed on
212- the screen. While the language item's name is ` panic_impl ` , the symbol name is
213- ` rust_begin_panic ` .
214-
215- Finally, a ` eh_catch_typeinfo ` static is needed for certain targets which
216- implement Rust panics on top of C++ exceptions.
108+ Note the use of ` abort ` : the ` exchange_malloc ` lang item is assumed to
109+ return a valid pointer, and so needs to do the check internally.
217110
218111## List of all language items
219112
220- This is a list of all language items in Rust along with where they are located in
221- the source code.
113+ An up-to-date list of all language items can be found [ here] in the compiler code.
222114
223- - Primitives
224- - ` i8 ` : ` libcore/num/mod.rs `
225- - ` i16 ` : ` libcore/num/mod.rs `
226- - ` i32 ` : ` libcore/num/mod.rs `
227- - ` i64 ` : ` libcore/num/mod.rs `
228- - ` i128 ` : ` libcore/num/mod.rs `
229- - ` isize ` : ` libcore/num/mod.rs `
230- - ` u8 ` : ` libcore/num/mod.rs `
231- - ` u16 ` : ` libcore/num/mod.rs `
232- - ` u32 ` : ` libcore/num/mod.rs `
233- - ` u64 ` : ` libcore/num/mod.rs `
234- - ` u128 ` : ` libcore/num/mod.rs `
235- - ` usize ` : ` libcore/num/mod.rs `
236- - ` f32 ` : ` libstd/f32.rs `
237- - ` f64 ` : ` libstd/f64.rs `
238- - ` char ` : ` libcore/char.rs `
239- - ` slice ` : ` liballoc/slice.rs `
240- - ` str ` : ` liballoc/str.rs `
241- - ` const_ptr ` : ` libcore/ptr.rs `
242- - ` mut_ptr ` : ` libcore/ptr.rs `
243- - ` unsafe_cell ` : ` libcore/cell.rs `
244- - Runtime
245- - ` start ` : ` libstd/rt.rs `
246- - ` eh_personality ` : ` libpanic_unwind/emcc.rs ` (EMCC)
247- - ` eh_personality ` : ` libpanic_unwind/gcc.rs ` (GNU)
248- - ` eh_personality ` : ` libpanic_unwind/seh.rs ` (SEH)
249- - ` eh_catch_typeinfo ` : ` libpanic_unwind/emcc.rs ` (EMCC)
250- - ` panic ` : ` libcore/panicking.rs `
251- - ` panic_bounds_check ` : ` libcore/panicking.rs `
252- - ` panic_impl ` : ` libcore/panicking.rs `
253- - ` panic_impl ` : ` libstd/panicking.rs `
254- - Allocations
255- - ` owned_box ` : ` liballoc/boxed.rs `
256- - ` exchange_malloc ` : ` liballoc/heap.rs `
257- - Operands
258- - ` not ` : ` libcore/ops/bit.rs `
259- - ` bitand ` : ` libcore/ops/bit.rs `
260- - ` bitor ` : ` libcore/ops/bit.rs `
261- - ` bitxor ` : ` libcore/ops/bit.rs `
262- - ` shl ` : ` libcore/ops/bit.rs `
263- - ` shr ` : ` libcore/ops/bit.rs `
264- - ` bitand_assign ` : ` libcore/ops/bit.rs `
265- - ` bitor_assign ` : ` libcore/ops/bit.rs `
266- - ` bitxor_assign ` : ` libcore/ops/bit.rs `
267- - ` shl_assign ` : ` libcore/ops/bit.rs `
268- - ` shr_assign ` : ` libcore/ops/bit.rs `
269- - ` deref ` : ` libcore/ops/deref.rs `
270- - ` deref_mut ` : ` libcore/ops/deref.rs `
271- - ` index ` : ` libcore/ops/index.rs `
272- - ` index_mut ` : ` libcore/ops/index.rs `
273- - ` add ` : ` libcore/ops/arith.rs `
274- - ` sub ` : ` libcore/ops/arith.rs `
275- - ` mul ` : ` libcore/ops/arith.rs `
276- - ` div ` : ` libcore/ops/arith.rs `
277- - ` rem ` : ` libcore/ops/arith.rs `
278- - ` neg ` : ` libcore/ops/arith.rs `
279- - ` add_assign ` : ` libcore/ops/arith.rs `
280- - ` sub_assign ` : ` libcore/ops/arith.rs `
281- - ` mul_assign ` : ` libcore/ops/arith.rs `
282- - ` div_assign ` : ` libcore/ops/arith.rs `
283- - ` rem_assign ` : ` libcore/ops/arith.rs `
284- - ` eq ` : ` libcore/cmp.rs `
285- - ` ord ` : ` libcore/cmp.rs `
286- - Functions
287- - ` fn ` : ` libcore/ops/function.rs `
288- - ` fn_mut ` : ` libcore/ops/function.rs `
289- - ` fn_once ` : ` libcore/ops/function.rs `
290- - ` generator_state ` : ` libcore/ops/generator.rs `
291- - ` generator ` : ` libcore/ops/generator.rs `
292- - Other
293- - ` coerce_unsized ` : ` libcore/ops/unsize.rs `
294- - ` drop ` : ` libcore/ops/drop.rs `
295- - ` drop_in_place ` : ` libcore/ptr.rs `
296- - ` clone ` : ` libcore/clone.rs `
297- - ` copy ` : ` libcore/marker.rs `
298- - ` send ` : ` libcore/marker.rs `
299- - ` sized ` : ` libcore/marker.rs `
300- - ` unsize ` : ` libcore/marker.rs `
301- - ` sync ` : ` libcore/marker.rs `
302- - ` phantom_data ` : ` libcore/marker.rs `
303- - ` discriminant_kind ` : ` libcore/marker.rs `
304- - ` freeze ` : ` libcore/marker.rs `
305- - ` debug_trait ` : ` libcore/fmt/mod.rs `
306- - ` non_zero ` : ` libcore/nonzero.rs `
307- - ` arc ` : ` liballoc/sync.rs `
308- - ` rc ` : ` liballoc/rc.rs `
115+ [ here ] : https://github.com/rust-lang/rust/blob/master/compiler/rustc_hir/src/lang_items.rs
0 commit comments