Miriについて
誰?
-
名前: r-chaser53
-
GitHub: https://github.com/rchaser53
-
Twitter: https://twitter.com/rChaser53
-
所属: LINE株式会社
-
何やってる人?
-
分類はフロントエンジニア
-
なんかいろいろやってます
-
このスライドは独自調査に基づいています
間違っていたら鼻で笑って許してください
Miriとは
MIR interpreter(Miri)
solsonさんが学部生の頃の研究の一環で作った
実験的なMIRのインタプリタ
従来のrustcではチェックできなかったようなことを
Miriはチェックすることができる
現状はrustc内で使われているのは
Constant Evaluationなどで使われている
2/23ごろにrust-langで管理されるようになった(※1)
MIRとは
mid-level intermediate representationの略
導入された理由
- コンパイル時間の短縮
- 実行時間の短縮
-
厳密な型検査のため
MIRとは
導入された理由をもう少し掘り下げる
- matchなどをdesugaringした結果を簡潔に表現するため
- control-flow graph(CFG)とコードを一致させるため
- LLVM IRとの差分を小さくするため(分析や差分の追従が楽)
- シンプルな構造のため安全性の証明がしやすくするため
- 最適化を楽にするため(容易で安全に最適化しやすい)
- ロジックを切り分けバックエンドの変更が容易にするため(LLVM以外を視野に入れられる)
他には何が?
順番に変換されていく。役割がそれぞれ違う
- AST 最初に生成
- HIR 型の検査に使用 (rust-clippyなどでも使用)
- HAIR MIRに変換する際に使用
- MIR borrowチェック、最適化に使用
- LLVM-IR 最適化、機械語生成に使用
Miriの処理順
solsonさんのスライドを引用。HAIRは省略されてる模様
何をしてくれるの?
以下のようなことに対してエラーを出力してくれる
- 範囲外のメモリアクセスとfreeしたメモリへのアクセス
- 初期化していないデータの使用
- unreachable!など実行されてはいけない処理が実行される
- 確保していないメモリや参照へのアクセス
- 型の定義に反した値の設定(enum、boolなど)
範囲外のメモリアクセス
fn main() {
let a = [1, 2, 3];
let b = 3;
a[b];
}
error[E0080]: constant evaluation error: index out of bounds: the len is 3 but the index is 3
--> src/main.rs:16:5
|
16 | a[b];
| ^^^^ index out of bounds: the len is 3 but the index is 3
|
rustc内でどう使われてるの?
Constant Evalulationなどで使われている模様
- const_evalを介して実行される
- 評価に必要な際に初めてconst_evalが呼び出される
// ここではまだ評価されない
const FOO: usize = 1 << 12;
// ここで初めて評価される
type Foo = [u8; FOO - 42];
使い方
使う前の事前準備
- rustcのバージョンを合わせる
- cargo cleanでtarget消す
- ~/.cache/miriを消す
正直とても面倒…
使い方
# rustcのバージョンの違いですぐ動かなくなるので
# 遊びたい際にちゃんとイメージから作る
git clone https://github.com/rchaser53/miri-slide-demo.git
cd miri-slide-demo
sh create.sh
# 開発しているレポジトリに移動して使う
cd path/to/project
docker run -it $(pwd):/home/app miri:ubuntu-18.04 bash
cargo +nightly miri run
Miriの成果
- Debug for vec_deque::Iter accessing uninitialized memory
- From<&[T]> for Rc creating a not sufficiently aligned reference
- BTreeMap creating a shared reference pointing to a too small allocation
- VecDeque creating overlapping mutable references
- Futures turning a shared reference into a mutable one
- str turning a shared reference into a mutable one
- BTreeMap creating mutable references that overlap with shared references
色々と既存のバグを解決している模様
感想
- 自作言語の調査のために調べ始めたが、必要な前提知識を身につけている間に大分経ってしまった
- オフでやってるわけだし楽しめればOKだよね?
- もう少しMIRがらみを調べてLLVM IRに変換するところを知りたい
- HIR、ASTなどの勉強が捗った
- rustfmtとかrust-clippyとかのPRを作るのに役立った
参考リンク
ご静聴ありがとうございました
Miriについて
By rchaser53
Miriについて
Miriがrust-langに入ったので改めて調べた話
- 2,454