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
, andadd
respectively. - panicking: the
panic
andpanic_impl
lang items, among others. - stack unwinding: the lang item
eh_personality
is a function used by the failure mechanisms of the compiler. This is often mapped to GCC's personality function (see thestd
implementation for more information), but programs which don't trigger a panic can be assured that this function is never called. Additionally, aeh_catch_typeinfo
static is needed for certain targets which implement Rust panics on top of C++ exceptions. - the traits in
core::marker
used to indicate types of various kinds; e.g. lang itemssized
,sync
andcopy
. - 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.