バグ報告ではじめるRustコントリビューション
これは Rust Advent Calendar 2021 13日目の記事です。
以下のバージョンの rustc に基づいています。
rustc 1.41.0 (5e1a79984 2020-01-27)
要約
- Rust コンパイラのバグを見つけたら気軽に Issue をたててみよう!
- 英語ができなくても、テンプレートに沿ってコードとエラーメッセージが貼れれば OK!
はじめに
Rust で遊んでいたらこのようなコードでコンパイラがクラッシュする (Internal Compiler Error: ICE) ことに気づきました
use std::time::{Duration, Instant};
use tokio::runtime::Runtime;
async fn foo() {
}
fn main() {
let mut rt = Runtime::new().unwrap();
let mut sum = Duration::new(0, 0);
let iteration = 10000;
for _ in 0..iteration {
sum += rt.block_on(async {
let start = Instant::now();
foo().await;
start.elapsed()
});
}
println!("duration: {}", sum.as_micros() as f64 / iteration as f64);
}
foo
の実行時間を計測するコードです。ところが、このコードは以下のようなエラーを吐き出します。
error: internal compiler error: src/librustc/middle/region.rs:1037: Encountered greater count 28 at span src/main.rs:13:31: 13:46 - expected no greater than 12
thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:905:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
note: rustc 1.41.0 (5e1a79984 2020-01-27) running on x86_64-unknown-linux-gnu
note: compiler flags: -C debuginfo=2 -C incremental --crate-type bin
note: some of the compiler flags provided by cargo are hidden
error: aborting due to previous error
調べてみると beta だけではなく stable バージョンでも同じエラーが出ることがわかったので、せっかくなので Issue 報告してみることにしました
はじめての Issue 報告
Issue 立ててみた
当時のコードはかなりの外部ライブラリに依存していたので、なるべく簡潔なコードになるように工夫しました。とりあえず以下のコードで ICE が再現することがわかったので、この内容で Issue を立ててみることにしました。
use tokio::prelude::*;
use tokio::runtime::Runtime;
use tokio::sync::mpsc;
fn main() {
let mut rt = Runtime::new().unwrap();
let mut sum = 0;
sum += rt.block_on(async {
let (tx, mut rx) = mpsc::unbounded_channel();
tx.send(1).unwrap();
while let Some(res) = rx.recv().await {
println!("{:?}", res);
}
1
});
}
Issue を立てるのは簡単です。New Issue
するとどのテンプレートを使うか聞かれるので、
今回は Internal Compiler Error
を選択します。このようなテンプレートができるので、必要事項を埋めていくだけで OK です。
できるだけコードを小さくすること、実行時に使った rustc のバージョンを明記することに気をつけるといいでしょう。
If you're using the stable version of the compiler, you should also check if the
bug also exists in the beta or nightly versions.
とあったので、 beta や nightly でも同様なエラーが出ることを確認しました。
というわけで Issue を立てることができました。 Issue のタイトルはどうすればいいかわからなかったので、エラーメッセージから適当につけておきました。
その後の流れ
6 時間後
T-compiler triage: P-high. Leaving nomination label in place, since I don't want to disrupt WG-async-await workflow.
https://github.com/rust-lang/rust/issues/69307#issuecomment-589017751
というコメントがつきました。 Stable でもバグらせているので優先度高めで取り組んでくれるらしいです。うれしい
9 時間後
Rust のコードをいじっていたら最初に提出したコードよりも小さいコードで同様の ICE を起こせることに気づいたので、報告しました。
use tokio::runtime::Runtime;
fn main() {
let mut rt = Runtime::new().unwrap();
let mut sum = 0;
sum += rt.block_on(async {
(async { }).await;
1
});
}
同時に、以下のようでは ICE が起きないことも報告しました
use tokio::runtime::Runtime;
fn main() {
let mut rt = Runtime::new().unwrap();
let mut sum = 0;
sum = sum + rt.block_on(async {
(async { }).await;
1
});
}
結論からいうと、今回のバグは +=
の右側に async/await
を書くとエラーが起きるというものでした。そのためこのコードはデバッグの助けになっていそうでした。 👍 がついてうれしい
22 時間後
外部ライブラリに依存しない minimum なコードの提案がありました。block_on
の書き方は自分では絶対気づけないやつですね...。こんな書き方できるんですね。
fn block_on<F>(_: F) -> usize {
0
}
fn main() {
let mut sum = 0;
sum += block_on(async {
(async {}).await;
1
});
}
35 日後
バグの原因の解析がされました
また、 PR が作成されました
49 日後
PR が merge されました 🎉
50 日後
rust-lang/glacier に収録されました。
このリポジトリは ICE を引き起こす Rust コードをあつめているようです。 Ice がたくさんあつまって氷河 (Glacier) になってしまったみたいです。
rustc 開発に参加しよう
今回は Issue を立てただけでしたが、自分で Issue を解決できる PR が作成できるようになるとかっこいいですよね。 rustc 開発に加わるのはかなり敷居が高そうなのですが、とっかかりによさそうな動画を見つけたので共有します
ラベルをみて Issue を絞ろう
初心者に有用なラベルが 3 つ紹介されていました。
E-mentor: メンターがついているラベルです。 Issue に取り組むなかで困ったときにメンターに相談できるそうです。
E-easy: コードの修正範囲が小さく、比較的簡単に解決できる Issue です。
P-low: 重要度・緊急度が低い Issue です。時間をかけてゆっくり取り組むことができます。
リソース
-
https://rustc-dev-guide.rust-lang.org/
- コンパイラの中身について詳しいです
-
https://rust-lang.zulipchat.com/
- バリバリ活躍している Contributor にヘルプを求めることができます
- Merge された PR や Close された Issue も参考になるようです
まとめ
Rust コンパイラがクラッシュすることに気づいたので Issue を立ててみました。思ったより早く解決されてびっくりしました。
みなさんも Rust コンパイラにバグを見つけたら、気軽に Issue を立ててみましょう。
Discussion