rust-lang/rustにコントリビュートした話

# はじめに

この記事は[Rust 3 Advent Calendar 2020](https://qiita.com/advent-calendar/2020/rust3)の13日目です。

最近[rust-lang/rust](https://github.com/rust-lang/rust)（つまりRustのコンパイラ本体）に初めてコントリビュートしたので、そのときの話を書いてみます。といっても何か機能を実装したとかではなく、ほんの一行追加しただけです。タイミング次第ではこんな簡単なコントリビュートもありますよ、というご紹介です。

ちなみに2日前のアドベントカレンダーの記事が大変参考になりますので、チャレンジしてみたい方はぜひご覧ください。

[rust-lang/rustへのcode contributionをはじめからていねいに](https://zenn.dev/fraternite/articles/4e11063bf05aac)

# 経緯

このコントリビュートはRedditかRust User ForumでSource-based code coverageについての投稿を見たことから始まりました。（Source-based code coverageについては[こちらの記事](https://qiita.com/dalance/items/69e18fe300760f8d7de0)をご参照ください）

投稿で紹介されていた[Issue](https://github.com/rust-lang/rust/issues/34701)を見に行くと、「[ここ](https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/source-based-code-coverage.html)にやりかた書いてあるから試してみて」となっているので早速試しました。すると、途中で使うツールであるllvm-covが見つかりません。

ここで、「なんでllvm-covはないんだろう？」と思いました。同じようなLLVM由来のツールであるllvm-profdataは以下のコマンドでインストール可能です。

```console
$ rustup component add llvm-tools-preview
```

これは以前[Profile Guided Optimization](https://doc.rust-lang.org/rustc/profile-guided-optimization.html)を試したときに入れていたので知っていました。
そこで、Issueに「llvm-covも配布したほうがいいよね？」と書きつつ、配布がどのように制御されているのか調査してみました。

rust-lang/rust以下でllvm-profdataを探すと以下のコードが見つかります。すなわち、この配列で配布するバイナリ一覧を定義しているということです。

```rust:src/bootstrap/lib.rs
const LLVM_TOOLS: &[&str] = &[
    "llvm-nm",       // used to inspect binaries; it shows symbol names, their sizes and visibility
    "llvm-objcopy",  // used to transform ELFs into binary format which flashing tools consume
    "llvm-objdump",  // used to disassemble programs
    "llvm-profdata", // used to inspect and merge files generated by profiles
    "llvm-readobj",  // used to get information from ELFs/objects that the other tools don't provide
    "llvm-size",     // used to prints the size of the linker sections of a program
    "llvm-strip",    // used to discard symbols from binary files to reduce their size
    "llvm-ar",       // used for creating and modifying archive files
    "llvm-dis",      // used to disassemble LLVM bitcode
    "llc",           // used to compile LLVM bytecode
    "opt",           // used to optimize LLVM bytecode
];
```

ということはここにllvm-covを追加すればいいはずです。追加してビルドしつつ、今度はrust-lang/rustの[CONTRIBUTING.md](https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md)を読みに行きました。こういった大きなプロジェクトではプルリクエストなどを出す手順が決まっていることが多いです。（たくさんの人が無秩序に出すと整理するのも大変ですからね）
さらに該当箇所のgit blameも見てみました。過去に新しいバイナリの配布を追加した人のPRを確認するためです。

機能追加などの場合は、まずRFCを書くところから（あるいは[Internals Forum](https://internals.rust-lang.org)での意見募集から）始まりますが、typo修正くらいなら直接PRが作成されるようです。

いろいろ見た結果、これくらいの変更ならいきなりPRにしてしまって良さそうだと判断してPRを作りました。

https://github.com/rust-lang/rust/pull/78947

rust-lang/rustではPRはコアチームの人に自動的に割り当てられます。割り当てられたMark-SimulacrumさんはさっそくSource-based code coverageの実装者であるrichkadelさんに「これで良さそう？」と聞いてくれました。richkadelさんもすぐに返事をしてくれて、PR作成から2時間後にはマージ開始されることになりました。
（最後のコメントの`@bors r+ rollup`がbotにマージを指示するコマンドになっています）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84296/a7605317-e923-db6d-c986-874e00902849.png)

その後CIが走るのを待って9時間後にマージが完了し、翌日のnightlyビルドに反映されました。これでllvm-covをllvm-tools-preview経由でインストールできるようになりました。

# コントリビュートすると

rust-langにコントリビュートした人は[Rust Contributors](https://thanks.rust-lang.org)に名前が載るのでちょっとうれしいです。ちなみにこのリストはrust-lang以下の全プロジェクトが対象なので、Rustコンパイラがハードル高い方は、周辺ツールからチャレンジしてみるといいのではないでしょうか。私は昔[rust-lang/mdbook]()のバグ修正をしたことがあったので、2回目のコントリビュートということになりました。