既存のプロジェクトのエディションを移行する

Rust には、プロジェクトのエディションを進めるための自動移行ツールが付属しています。 このツールは、あなたのソースコードを書き換えて次のエディションに適合させます。 簡単にいうと、新しいエディションに進むためには次のようにすればよいです。

  1. cargo fix --edition を実行する
  2. Cargo.tomledition フィールドを新しいエディションに設定する。たとえば、 edition = "2021" とする
  3. cargo buildcargo test を実行して、修正がうまくいったことを検証する。

以下のセクションで、これらの手順の詳細と、その途中で起こりうる問題点について詳しく説明します。

我々は、新しいエディションへの移行をできるだけスムーズに行えるようにしたいと考えています。 もし、最新のエディションにアップグレードするのが大変な場合は、我々はそれをバグとみなします。 もし移行時に問題があった場合にはバグ登録してください。 よろしくお願いします!

訳注:Rustの日本語コミュニティもあります。 Slackを使用しておりこちらから登録できます。

移行の開始

例えば、2015エディションから2018エディションに移行する場合を見てみましょう。 ここで説明する手順は、例えば2021エディションのように、別のエディションに移行する場合も実質的に同様です。

src/lib.rsに以下のコードがあるクレートがあるとします。


#![allow(unused)]
fn main() {
trait Foo {
    fn foo(&self, i32);
}
}

このコードは i32 という無名パラメータを使用しています。 これは Rust 2018ではサポートされておらず、コンパイルに失敗します。 このコードを更新してみましょう。

あなたのコードを新しいエディションでコンパイルできるようにする

あなたのコードは新しいエディションに互換性のない機能を使っているかもしれないし、使っていないかもしれません。 Cargo には cargo fix というサブコマンドがあり、これがあなたのコードを自動的に更新して次のエディションへの移行を補助してくれます。 まず初めに、これを実行してみましょう。

cargo fix --edition

これはあなたのコードをチェックして、自動的に移行の問題を修正してくれます。 もう一度 src/lib.rsを見てみましょう。


#![allow(unused)]
fn main() {
trait Foo {
    fn foo(&self, _: i32);
}
}

i32 値をとるパラメータに名前が追加された形でコードが書き換えられています。 この場合は、パラメータ名がなかったので、使用されていないパラメータの慣習に従って _ を付加しています。

cargo fixは常に自動的にコードを修正してくれるわけではありません。 もし、cargo fixがコードを修正できない時にはコンソールに修正できなかったという警告を表示します。 その場合は手動でコードを修正してください。 「発展的な移行戦略の章では、移行に関するより多くの情報があります。また、このガイドの他の章では、どのような変更が必要かについても説明しますので、併せてご参照ください。 問題が発生したときは、ユーザーフォーラム で助けを求めてください。

新機能を使うために新たなエディションを有効化する

新しいエディションの新機能を使うには明示的にオプトインする必要があります。 準備がよければ、Cargo.toml に新しい edition のキーバリューペアを追加してください。 例えば以下のような形になります。

[package]
name = "foo"
version = "0.1.0"
edition = "2018"

もし edition キーがなければCargoはデフォルトで Rust 2015をエディションとして使います。 しかし、上記の例では 2018 を明示的に指定しているので、コードは Rust 2018 でコンパイルされます!

次に、新しいエディション上であなたのプロジェクトをテストしましょう。 cargo test を実行するなどして、プロジェクトのテストを走らせ、すべてが元のまま動くことを確認してください。 新たに警告が出た場合、(--edition なしの) cargo fix をもう一度実行することで、コンパイラからの提案を受け入れてみるのも良いかもしれません。

わーい。今やあなたのコードは Rust 2015 と Rust 2018 の両方で有効です!