エディションとは?

Rust 1.0 のリリースでは、Rust のコア機能として「よどみない安定性」が提供されるようになりました。 Rust は、1.0 のリリース以来、いちど安定版にリリースされた機能は、将来の全リリースに渡ってサポートし続ける、というルールの下で開発されてきました。

一方で、後方互換でないような小さい変更を言語に加えることも、ときには便利です。 最もわかりやすいのは新しいキーワードの導入で、これは同名の変数を使えなくします。 例えば、Rust の最初のバージョンには asyncawait といったキーワードはありませんでした。 後のバージョンになってこれらを突然キーワードに変えてしまうと、例えば let async = 1; のようなコードが壊れてしまいます。

このような問題を解決するために、エディションという仕組みが使われています。 後方互換性を失わせるような機能をリリースしたいとき、我々はこれを新しいエディションの一部として提供します。 エディションはオプトイン、すなわち導入したい人だけが導入できるので、既存のクレートは明示的に新しいエディションに移行しない限りは変化を受けません。 すなわち、2018 以降のエディションを選択しない限り、たとえ最新バージョンの Rust であっても async はキーワードとして扱われません。 導入の可否はクレートごとに決めることができ、Cargo.toml への記載内容により決定されます。 cargo new コマンドで作成される新しいクレートは、常に最新の安定版のエディションでセットアップされます。

エディションはエコシステムを分断しない

エディションで最も重要な規則は、あるエディションのクレートと別のエディションでコンパイルされたクレートがシームレスに相互運用できるようになっているということです。 これにより、新しいエディションへ移行するかどうかは、他のクレートに影響を与えない「自分だけの問題」だと言えるのです。

クレートの相互運用性を守るために、我々がエディションに加えられる変更にはある種の制限がかかります。 一般に、エディションに加えられる変更は「表面上の」ものになりがちです。 エディションに関わらず、すべての Rust のコードは最終的にはコンパイラの中で同じ内部表現に変換されるのです。

エディションの移行は簡単で、ほとんど自動化されている

我々は、クレートを新しいエディションにアップグレードするのが簡単になるよう目指しています。 新しいエディションがリリースされるとき、我々は移行を自動化するツールも提供します。 このツールは、新しいエディションに適合させるために必要な小さな変更をコードに施します。 例えば、Rust 2018 への移行の際は、async と名のつく全てのものを、等価な生識別子構文である r#async へと書き換える、といった具合です。

この自動移行は必ずしも完璧とは限らず、手作業での変更が必要なコーナーケースもないとは言えません。 このツールは、コードの正しさやパフォーマンスに影響を与えうるような、プログラムの意味に関わる変更は避けるために全力を尽くします。

我々はこのツールの他に、エディションを構成する変更を取り扱っている、本エディション移行ガイドも管理しています。 このガイドでは、それぞれの変更内容と、もっと詳しく知りたい人向けのリンク、さらには知っておくべき詳細や重箱の隅まで網羅しています。 このガイドはエディションの概要を示すと同時に、自動化ツールに何らかの問題が生じたときのトラブルシューティング用の文献にもなります。