lang_items
The tracking issue for this feature is: None.
The rustc compiler has certain pluggable operations, that is,
functionality that isn't hard-coded into the language, but is
implemented in libraries, with a special marker to tell the compiler
it exists. The marker is the attribute #[lang = "..."] and there are
various different values of ..., i.e. various different 'lang
items'. Most of them can only be defined once.
Lang items are loaded lazily by the compiler; e.g. if one never uses Box
then there is no need to define a function for exchange_malloc.
rustc will emit an error when an item is needed but not found in the current
crate or any that it depends on.
Some features provided by lang items:
- overloadable operators via traits: the traits corresponding to the
==,<, dereferencing (*) and+(etc.) operators are all marked with lang items; those specific four areeq,partial_ord,deref/deref_mut, andaddrespectively. - panicking: the
panicandpanic_impllang items, among others. - stack unwinding: the lang item
eh_personalityis a function used by the failure mechanisms of the compiler. This is often mapped to GCC's personality function (see thestdimplementation for more information), but programs which don't trigger a panic can be assured that this function is never called. Additionally, aeh_catch_typeinfostatic is needed for certain targets which implement Rust panics on top of C++ exceptions. - the traits in
core::markerused to indicate types of various kinds; e.g. lang itemssized,syncandcopy. - memory allocation, see below.
Most lang items are defined by core, but if you're trying to build
an executable without the std crate, you might run into the need
for lang item definitions.
Example: Implementing a Box
Box pointers require two lang items: one for the type itself and one for
allocation. A freestanding program that uses the Box sugar for dynamic
allocations via malloc and free:
#![feature(lang_items, start, core_intrinsics, rustc_private, panic_unwind, rustc_attrs)]
#![allow(internal_features)]
#![no_std]
extern crate libc;
extern crate unwind;
use core::ffi::c_void;
use core::intrinsics;
use core::panic::PanicInfo;
use core::ptr::NonNull;
pub struct Global; // the global allocator
struct Unique<T>(NonNull<T>);
#[lang = "owned_box"]
pub struct Box<T, A = Global>(Unique<T>, A);
impl<T> Box<T> {
pub fn new(x: T) -> Self {
#[rustc_box]
Box::new(x)
}
}
impl<T, A> Drop for Box<T, A> {
fn drop(&mut self) {
unsafe {
libc::free(self.0.0.as_ptr() as *mut c_void);
}
}
}
#[lang = "exchange_malloc"]
unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
let p = libc::malloc(size) as *mut u8;
// Check if `malloc` failed:
if p.is_null() {
intrinsics::abort();
}
p
}
#[start]
fn main(_argc: isize, _argv: *const *const u8) -> isize {
let _x = Box::new(1);
0
}
#[lang = "eh_personality"]
fn rust_eh_personality() {}
#[panic_handler]
fn panic_handler(_info: &PanicInfo) -> ! { intrinsics::abort() }
Note the use of abort: the exchange_malloc lang item is assumed to
return a valid pointer, and so needs to do the check internally.
List of all language items
An up-to-date list of all language items can be found here in the compiler code.