注意: 最新版のドキュメントをご覧ください。この第1版ドキュメントは古くなっており、最新情報が反映されていません。リンク先のドキュメントが現在の Rust の最新のドキュメントです。
注意 : 言語アイテムは大抵Rustの配布物内のクレートから提供されていますし言語アイテムのインターフェース自体安定していません。 自身で言語アイテムを定義するのではなく公式の配布物のクレートを使うことが推奨されています。
rustc
コンパイラはあるプラガブルな操作、つまり機能が言語にハードコードされているのではなくライブラリで実装されているものを持っており、特別なマーカによってそれが存在することをコンパイラに伝えます。
マーカとは #[lang = "..."]
アトリビュートで、 ...
には様々な値が、つまり様々な「言語アイテム」あります。
例えば、 Box
ポインタは2つの言語アイテムを必要とします。1つはアロケーションのため、もう1つはデアロケーションのため。
フリースタンディング環境で動くプログラムは Box
を malloc
と free
による動的アロケーションの糖衣として使います。
#![feature(lang_items, box_syntax, start, libc)] #![no_std] extern crate libc; extern { fn abort() -> !; } #[lang = "owned_box"] pub struct Box<T>(*mut T); #[lang = "exchange_malloc"] unsafe fn allocate(size: usize, _align: usize) -> *mut u8 { let p = libc::malloc(size as libc::size_t) as *mut u8; // malloc failed if p as usize == 0 { abort(); } p } #[lang = "exchange_free"] unsafe fn deallocate(ptr: *mut u8, _size: usize, _align: usize) { libc::free(ptr as *mut libc::c_void) } #[lang = "box_free"] unsafe fn box_free<T>(ptr: *mut T) { deallocate(ptr as *mut u8, ::core::mem::size_of::<T>(), ::core::mem::align_of::<T>()); } #[start] fn main(argc: isize, argv: *const *const u8) -> isize { let x = box 1; 0 } #[lang = "eh_personality"] extern fn eh_personality() {} #[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
abort
を使ってることに注意して下さい: exchange_malloc
言語アイテムは有効なポインタを返すものとされており、内部でその検査をする必要があるのです。
言語アイテムによって提供される機能には以下のようなものがあります。:
==
、 <
、 参照外し( *
) そして +
(など)の演算子は全て言語アイテムでマークされています。
これら4つはそれぞれ eq
、 ord
、 deref
、 add
ですeh_personality
、 fail
そして fail_bounds_check
言語アイテムです。std::marker
内のトレイトで様々な型を示すのに使われています。 send
、 sync
そして copy
言語アイテム。std::marker
にある変性指示子。 covariant_type
、 contravariant_lifetime
言語アイテムなどなど。言語アイテムはコンパイラによって必要に応じてロードされます、例えば、 Box
を一度も使わないなら exchange_malloc
と exchange_free
の関数を定義する必要はありません。
rustc
はアイテムが必要なのに現在のクレートあるいはその依存するクレート内で見付からないときにエラーを出します。