コーディング規約
この章では、フォーマット、正しさのためのコーディング、 crates.io のクレートの使用、およびレビューしやすい PR の構成に関するヒントを扱います。
フォーマットと tidy スクリプト
rustc は Rust の標準コーディングスタイルに移行しつつあります。
ただし、現時点では stable rustfmt は使用していません。特別な設定を持つ
固定されたバージョンを使用しているため、通常の rustfmt とは異なるスタイルになる可能性があります。
したがって、このリポジトリを cargo fmt でフォーマットすることは推奨されません。
代わりに、フォーマットは ./x fmt を使って行うべきです。
後でコンフリクトが減るため、各コミットの前に ./x fmt を実行する習慣をつけるとよいでしょう。
フォーマットは tidy スクリプトによってチェックされます。
これは ./x test を実行したときに自動的に実行され、./x fmt --check で単独でも実行できます。
注: フォーマットとテストスイート
tests/ディレクトリ配下のほとんどの Rust ソースファイルは、空白に敏感であること、 スナップショットテストの性質、位置に敏感なコメントなどの理由によりフォーマットされていません。どのテストファイルがフォーマットされないかについては、 https://github.com/rust-lang/rust/blob/main/rustfmt.toml の
ignoreエントリを参照してください。
エディターで保存時フォーマットを使用したい場合、固定されたバージョンの
rustfmt は build/<target>/stage0/bin/rustfmt 配下にビルドされています。
C++ コードのフォーマット
コンパイラには、安定した C API を持たない LLVM の一部と連携するための C++ コードが含まれています。 そのコードを変更する場合は、次のコマンドを使ってフォーマットしてください。
./x test tidy --extra-checks cpp:fmt --bless
これは、ローカル環境に依存しないように、固定されたバージョンの clang-format を使用します。
Python コードのフォーマットと lint
Rust リポジトリにはかなり多くの Python コードが含まれています。 私たちは ruff ツールによって、それらが lint され、フォーマットされた状態を保つようにしています。
Python コードを変更する場合は、次のコマンドを使ってフォーマットしてください。
./x test tidy --extra-checks py:fmt --bless
そして、lint を実行するには次のコマンドを使用します。
./x test tidy --extra-checks py:lint
これらは、ローカル環境に依存しないように、固定されたバージョンの ruff を使用します。
著作権表示
以前は、ファイルは著作権とライセンスの表示で始まっていました。 標準の条件(MIT OR Apache-2.0)でライセンスされる新しいファイルでは、この表示を省略してください。
著作権表示は現在ではすべてなくなっているはずですが、rust-lang/rust リポジトリで 見かけた場合は、それを削除する PR を遠慮なく開いてください。
行の長さ
行は最大 100 文字にするべきです。 80 文字以内に収められればなおよいです。
場合によっては、特にテストでは、この制限から除外する必要があることがあります。 その場合は、次のようにファイルの先頭付近にコメントを追加できます。
#![allow(unused)]
fn main() {
// ignore-tidy-linelength
}
タブとスペース
4 スペースのインデントを優先してください。
正しさのためのコーディング
フォーマット以外にも、従う価値のあるヒントがいくつかあります。
網羅的な match を優先する
match で _ を使用するのは便利ですが、enum に新しいバリアントが追加されたとき、
それらが正しく処理されない可能性があることを意味します。
自問してみてください。この enum に新しいバリアントが追加された場合、それが
_ のコードを使いたい可能性と、別の処理を必要とする可能性はどちらが高いでしょうか。
答えが「低い」でない限り、網羅的な match を優先してください。
同じ助言は if let と while let にも当てはまります。
これらは実質的に単一のバリアントに対するテストです。
忘れたくないことには “TODO” コメントを使う
自分自身にとって便利なツールとして、PR をマージする前に戻って対応したいことに
// TODO コメントを挿入できます。
fn do_something() {
if something_else {
unimplemented!(); // TODO これを書く
}
}
tidy スクリプトは // TODO コメントに対してエラーを報告するため、この
コードは TODO が修正される(または削除される)までマージできません。
これは PR 内で、あるコミットではバグを残しておき、後のコミットで修正することを 示す方法としても有用です。
if foo {
return true; // TODO 誤りだが、後のコミットで修正される
}
コードベースにメモを残したい場合は、代わりに // FIXME を使用してください。
crates.io のクレートの使用
crates.io の依存関係セクションを参照してください。
PR の構成方法
PR のコミットをどのように準備するかは、レビュー担当者にとって大きな違いを生みます。 以下にいくつかのヒントを示します。
「純粋なリファクタリング」は独立したコミットに分離してください。 たとえば、 メソッドの名前を変更する場合は、その名前変更を、そのすべての使用箇所の名前変更とともに、 独立したコミットに入れてください。
通常、コミットは多いほうがよいです。 大きな変更を行っている場合、 独立して理解できる小さなステップに分割するほうが、ほとんど常に望ましいです。 注意すべき点が 1 つあります。ある戦略に従ってコードを導入した後で、後のコミットで それを大幅に変更する(追加するのではなく)場合、その「行ったり来たり」は混乱を招く可能性があります。
積極的にフォーマットしてください。 PR の最後のコミットだけが正しく
フォーマットされている必要がありますが、各コミットを ./x fmt で個別にフォーマットするほうが、
レビューしやすく、ノイズも少なくなります。
マージ禁止。 bors によるものを除き、私たちは履歴へのマージコミットを許可していません。
マージコンフリクトが発生した場合は、代わりに
git rebase --interactive rust-lang/main のようなコマンドで rebase してください
(remote に rust-lang という名前を使用していると仮定しています)。
個々のコミットはビルドできなくてもかまいません(ただし、できると望ましいです)。 私たちは すべての中間コミットが正常にビルドできることを要求していません。PR レベルで bisect できることだけを期待しています。 ただし、個々のコミットをビルド可能にできるなら、それは常に助けになります。
命名規則
通常の Rust のスタイルや命名規則に加えて、コンパイラ固有のものもいくつかあります。
-
cxは “context” の短縮形であることが多く、サフィックスとしてよく使われます。 たとえば、tcxは Typing Context の一般的な名前です。 -
'tcxは Typing Context のライフタイム名として使用されます。 -
crateはキーワードであるため、クレート関連の何かを表す変数が必要な場合、 多くの場合、綴りをkrateに変更します。