はじめに

Swift Compilerについて

普段Swiftを書く際は、あまりコンパイラがどう動いているか気にする機会は少ないと思います。Swiftは言語仕様として多くの機能を持っていますが、それを難なく使えるのはコンパイラが色々なことを面倒見ているからです。その中には地味で泥臭い内容もありますが、そのおかげでいつもSwiftを快適に書けています。

Swiftを書くエンジニアとして、Swift Compilerがどういう仕組みで動いているか理解できれば面白いと思いませんか?もし、Swift Compilerの気持ちを理解できれば、Swiftらしいコードを書けるはずです。また、いいパファーマンスになるようにもコードを書けるかもしれません。もしくは勢い余ってコンパイラの改善にコントリビュートするのも楽しいと思います。この本を通してコンパイラのことをよく知り、さらに楽しくSwiftを書きましょう。

対象読者

本書の対象読者は、次のように想定しています。

  • Swift Compilerに興味がある
  • Swiftの言語仕様に興味がある
  • Swift Compilerにコントリビュートしてみたい

動作環境

本書は次の環境に準拠しています。

  • Swift 5.2

第1章 Swift Compilerの概要

1.1 Swift Compiler

SwiftWWDC (Worldwide Developers Conference) 2014 で発表されたプログラミング言語です。主にiOS, macOS, Linuxで利用されることを想定されていますが、Windowsなど他のプラットフォーム*1の対応も今後予定されています。Swiftの概要や特徴はこちらをご覧ください。*2

Swiftのコンパイラである Swift Compiler の開発は2010年に始まり、主にC++で書かれています。当時はApple社内で開発されていましたが、2015年にオープンソースとなりGitHubでホスティングされています。*3それ以降もAppleのコンパイラチームやコミュニティによって活発に開発が続いており、Swiftの公式バージョンは現時点で5.2が最新です。*4

最新バージョンのリリース情報や特徴的な機能の解説などは、公式のブログ *5 で公開されています。気になる方はこちらを定期的にチェックするのをお勧めします。

1.2 LLVM

Swift Compilerはバックエンドに LLVM を使用しています。*6WikipediaにはLLVMの定義は次のように記載されています。*7

LLVMとは、コンパイル時、リンク時、実行時などあらゆる時点でプログラムを最適化するよう設計された、任意のプログラミング言語に対応可能なコンパイラ基盤である。LLVMは、まず仮想機械をターゲットとした中間コード(ビットコード)を生成し、その仮想機械向けコードを特定のマシンの機械語に変換する。この時言語やプラットフォームとは独立した最適化を行う。この方法によってLLVMは言語からもアーキテクチャからも独立しており、それぞれに特化した、プログラミング言語固有のモジュールと、マシン向けコード生成部を用意することにより様々な言語アーキテクチャーに対応する。

Swiftの他にも、C++はもちろんのことRust*8やJulia*9などさまざまなプログラミング言語がLLVMを使用して開発されています。

最初のうちはSwift Compilerのフロントエンドのみ触れるので十分です。ただ、プログラムにおける根幹の最適化にも興味がある方は、あとでLLVMも少し覗いてみるといいと思います。

1.3 ガイドライン

Swift Compilerの開発はオープンに行われているので、コミュニティガイドラインが公開されています。簡単にその内容を紹介しますが、詳細が気になる方はこちらもご覧ください。*10

1.4 Swift Forums

Swift Compilerに関するテクニカルな話やプロジェクト管理に関する議論は Swift Forums *11で行います。パブリックな場所でのコミュニケーションが推奨されていて、Swiftの開発に関わるアクティブなエンジニアが関連するカテゴリを常にモニターしています。

円滑な議論を促進するために、Forumsには カテゴリー が作成されています。いくつか重要なものだけピックアップして紹介します。

Announcements

Swiftに関連する全てのプロジェクトの重要なアナウンスに関するカテゴリーです。 *12Swiftバージョンのリリース情報や、新しいプロジェクトの概要などに対して使われています。

たとえば、最近だと On the road to Swift 6 *13 で Swift 6 へ向けたアナウンスなどが投稿されています。

Using Swift

Swiftを最近始めた方や元々興味を持っていた方のためのカテゴリーです。 *14Swiftや周辺ツールに関する色々な質問や要望を投稿できます。

たとえば、 Cross-Compiling macOS to Linux *15 で クロスコンパイルについての質問などが投稿されています。

Development

Swiftに関連する開発や実装に関して議論するカテゴリーです。 *16Swift Compiler, Standard Library, Core Libraries, LLDB, SwiftPM などのサブカテゴリーが用意されています。

たとえば、最近だと WASM support *17 で WASM サポートに向けた対応の近況報告などが投稿されています。

Swift Evolution

Swiftへの新しい仕様・機能を提案するカテゴリーです。 *18Appleのコンパイラチームやコミュニティなど所属にかかわらず、それらの開発は Swift Evolution で提案して議論することが推奨されています。

  • Announcements

Evolutionへの提案のレビューや結果をアナウンスに関するサブカテゴリーです。

  • Pitches

新しい言語仕様や、スタンダードライブラリの新しいAPIなどの提案に関するサブカテゴリーです。

  • Proposal Reviews

提案された内容のレビューに関するサブカテゴリーです。

  • Discussion

Swift Evolutionについての一般的な議論に関するサブカテゴリーです。

レビュープロセスが始まった提案に関しては、GitHubのレポジトリでステータス管理を行っています。 *19また、このリポジトリのREADME.mdには直近開発しているバージョンの特徴的な機能についての概要も記載されています。

たとえば、最近だと Modify Accessorsmodify *20 というアクセス修飾子の提案ピッチが投稿されています。

1.5 Swift Bugs

Swift Compilerに関するバグの議論は Swift Bugs *21で行います。バグかどうか分からない内容でも、質問や要望としてここに投稿されることもあります。バグレポートは粒度を問わずSwiftの改善に非常に重要です。少しでも気になることがあれば、気軽に投稿するのをお勧めします。

バグレポートする際は、再現手順など正確な説明、テストケースの対応、環境設定の情報などを記載するのが推奨されています。詳しくはこちらも参照にしてください。 *22

ただし、Swiftのベータバージョンで実装されている機能などNDAに触れる内容は、 Bug Reports *23 で報告する決まりになっています。

1.6 コントリビューション

Swift Compilerに向けたコントリビューションはどのような内容でも歓迎されます。ガイドラインとして推奨されている作法や内容があるので、簡単にいくつか紹介します。

バグ修正

まずは良く行われるバグ修正について、方針となる内容が明記されているので紹介します。 *24

  • Reproduce bugs

再現可能な状態にする必要があります。もしどうしても再現できない場合は、自分なりに理由を考えたり、バグ報告者が別に居る場合はコンタクトを取って状況を聞いてみるのがよいでしょう。

  • Reduce bugs

再現可能な状態にできたら、できる限りコード量を減らして最小限の変更に留めましょう。不要なコードが含まれるのは良い例ではありません。

  • Eliminate duplicate bugs

もし同じようなバグ報告が上がってる場合は、新しく報告されたほうを重複扱いにしましょう。そうすることで、他の人が取り組む際に効率よく進められます。

一般的な変更

バグ修正に問わず、どのような変更にも当てはまる一般的な方針を紹介します。

  • 大きな、もしくは破壊的な変更は、クリーンアップや小さなリファクタリングなど補助的な変更を含む可能性が高いです。それらは前もって別のコミットにして作業しましょう。
  • 可能であれば、相関性のある変更だけに分解して作業を進めましょう。もしくは、事前にゴールを議論してコンセンサスを取るのもよいかもしれません。
  • それぞれの変更を独立させるか、もしくは連続したPRにするのがよいです。そしてそれらの関係性を分かりやすく説明するのがレビューに役立ちます。

コミットメッセージ

次は理想のコミットメッセージを紹介します。必ずこのとおりに従う必要はないので、参考程度に留めてください。

  • コミットメッセージの1行目はタイトルを記載して、それ以外の詳細がある場合はボディに書きましょう。タイトルとボディの間は空行を入れましょう。
  • タイトルやボディは正確で端的に書きましょう
  • 特定の箇所への変更の場合は、 [Parser][SILGen] などのタグを先頭に付けましょう
  • バグ修正をした場合にバグレポートのリンクがあれば記載しましょう
  • ソース内のコメントフォーマットと同様に、大文字始まりやピリオドを使用しましょう
  • 他の変更へのバグ修正や、リバートの場合など、該当するコミットハッシュを追加しましょう

他にも知っておくと多少は参考になる情報があるので、気になる方はこちらも参照してください。 *25

お勧めタスク

Swift Bugsには StarterBug *26 というラベルが用意されています。用途は名前のとおりで、Swift Compilerにはじめて取り組む方のためのラベルです。このラベルが付いているタスクは、比較的簡単でなおかつ少ない変更で済む修正が多いです。興味がある方は参考にしてください。

タイポの修正や小さなリファクタリングの変更は、GitHubのPRタイトルに [Gardening] と付けることが多いです。最初のコントリビューション内容は上記のような内容になるかもしれません。GitHubでPRを作る際に過去の例 *27 を参考にしてみてください。

また取り組みやすい内容として、 エラー診断である Diagnostics の修正があります。コンパイルエラーの文言を親切にしたり、何らかのバグでコンパイルエラーになる機能を修正する入り口になります。これらの修正は、GitHubのPRタイトルに [Qol] と付けることが多いです。第3章 で各モジュールがどのような診断をするか簡単に説明しているので、参考にしてください。

1.7 Documentations

ドキュメントはapple/swiftリポジトリの docs フォルダにあります。

まずは Lexicon.rst *28 を見るのがよいと思います。Lexiconとは用語集という意味なので、Swift Compilerでよく使われている用語の簡単な説明があります。たとえば、 AST, existential, LLVM IR, metatype, SIL, stdlib, value witness table, vtable などがあります。もちろん全てを網羅できている訳ではないですが、頻繁に目にする用語が多いのでさっと目を通すことをお勧めします。

全体的にドキュメントは数多く書かれているので、最初は興味のあるドキュメントのみ読むのをお勧めします。Swift Compilerの代表的な機能の Type Checker *29Generics *30SIL *31 などのドキュメントがあります。またマニフェストとして、 API Stability Manifesto *32Ownership Manifesto *33 などのドキュメントもあります。

上で挙げたドキュメントだけでも全部読んで理解するのはかなり苦労します。もしかしたら、テストコードや実装と見比べながらじゃないと理解するのが難しいかもしれません。ただ最初は分からないことが多いと思うので、あまり気にする必要はないと思います。少しづつ調べながら理解できるようになりましょう。

試し読みはここまでです。
この続きは、製品版でお楽しみください。