Rustの名前解決の仕組み: Prelude
Rustにはpreludeという名前解決の仕組みがある。これについて調べる。
preludeとは
preludeとは、crate内の全てのmoduleのスコープに自動的に取り込まれる名前の集まり。名前解決に使われる。
例えば、Boxという名前は (#![no_std]がない限り) 全てのmoduleで使うことができる。それにもかかわらずself::Boxなど存在しない。これはBoxがmodule自体の持つ名前ではなく、preludeに存在する名前であるため。
5種類のprelude
preludeにはいくつか種類がある。
- standard library prelude
- extern prelude
- language prelude
-
macro_useprelude - tool prelude
standard library prelude
全てのcrateはstandard library preludeを持つ。このstandard library preludeは1つのmoduleから成るが、そのmoduleはcrateのedition ("2015" or "2018" or "2021") と#![no_std]が適用されているかどうかによって異なる。
#![no_std]が適用されていない場合はstd::prelude::rust_<edition>、適用されている場合はcore::prelude::rust_<edition>がstandard library preludeとなる。
extern prelude
extern crateやコンパイラーの--externオプションでインポートされたcrateたちはextern preludeに追加される。(もしextern crate orig_name as new_nameとaliasでインポートされたらnew_nameの方が追加される。)
coreは常にextern preludeに追加される。#![no_std]がない限り、stdも追加される。
extern preludeを使った実験
extern preludeを使うとちょっとしたことができる。
2つのファイルを用意する。
// ./main.rs
fn main() {
hi::say_hi();
}
// hi.rs
pub fn say_hi() {
println!("Hi.");
}
hi.rsをrlibとしてコンパイルし (libhi.rlib)、main.rsをコンパイルする際にlibhi.rlibをhi crateとしてextern preludeに追加する。
$ rustc --crate-type=rlib ./hi.rs
$ rustc --extern hi=$(pwd)/libhi.rlib main.rs
$ ./main
Hi.
std libraryなどではないものが、ビルトインみたいに使える。
language prelude
language preludeには、型 (bool, char, str, i32, ...) やattribute (cfg, derive, proc_macro, ...) の名前が含まれる。
macro_use prelude
macro_use preludeには、extern crateのmacro_use attributeでインポートされた、外部crateのmacroが含まれる。
ここにstdからエクスポートされた全てのmacroが含まれる。#![no_std]の場合はstdではなくcoreとなる。
tool prelude
tool preludeには、#[rustfmt::skip]や#[clippy::cyclomatic_complexity = "100"]といったtool attributesの名前が含まれる。
no_implicit_prelude attribute
crateまたはmoduelに#![no_implicit_prelude]を適用すると、standard library prelude、extern prelude、tool prelude、macro_use preludeを自動的にスコープに取り入れることがなくなる。(language preludeには影響なし。) これは子孫moduleにも適用される。
なお、#![no_std]との名前の一貫性を理由に#![no_implicit_prelude]を#![no_prelude]にリネームして、さらに対象のmoduleのみに影響するようにする、というRFC: rust-lang/rfcs#501があるようだ。ただ、このRFCのtracking issueが2022年にcloseされた (能力とやる気のある人待ちのようだ。) ので進捗はないみたい。
Discussion