@@ -9,26 +9,60 @@ functionality that isn't hard-coded into the language, but is
9
9
implemented in libraries, with a special marker to tell the compiler
10
10
it exists. The marker is the attribute ` #[lang = "..."] ` and there are
11
11
various different values of ` ... ` , i.e. various different 'lang
12
- items'.
12
+ items'. Most of them can only be defined once.
13
13
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 ` :
17
47
18
48
``` 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)]
20
50
#![allow(internal_features)]
21
51
#![no_std]
52
+
53
+ extern crate libc;
54
+ extern crate unwind;
55
+
56
+ use core::ffi::c_void;
22
57
use core::intrinsics;
23
58
use core::panic::PanicInfo;
24
59
use core::ptr::NonNull;
25
60
26
- extern crate libc;
27
-
61
+ pub struct Global; // the global allocator
28
62
struct Unique<T>(NonNull<T>);
29
63
30
64
#[lang = "owned_box"]
31
- pub struct Box<T>(Unique<T>);
65
+ pub struct Box<T, A = Global >(Unique<T>, A );
32
66
33
67
impl<T> Box<T> {
34
68
pub fn new(x: T) -> Self {
@@ -37,272 +71,45 @@ impl<T> Box<T> {
37
71
}
38
72
}
39
73
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
+
40
82
#[lang = "exchange_malloc"]
41
83
unsafe 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;
43
85
44
86
// Check if `malloc` failed:
45
- if p as usize == 0 {
87
+ if p.is_null() {
46
88
intrinsics::abort();
47
89
}
48
90
49
91
p
50
92
}
51
93
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
-
58
94
#[start]
59
95
fn main(_argc: isize, _argv: *const *const u8) -> isize {
60
96
let _x = Box::new(1);
61
97
62
98
0
63
99
}
64
100
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.
178
101
#[lang = "eh_personality"]
179
- #[no_mangle]
180
- pub extern fn rust_eh_personality() {
181
- }
102
+ fn rust_eh_personality() {}
182
103
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() }
188
106
```
189
107
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.
217
110
218
111
## List of all language items
219
112
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.
222
114
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