Rust 2024エディションが安定版ツールチェーンに載った今、移行は「書き直し」ではなく、CIで段階的に進められる運用作業です。

この記事では、Rust 1.85.0を軸にした2024エディション移行の手順と、async運用・WASM/WASI・FFI境界・CI運用など、2026年の実務で押さえる論点を整理します。

この記事でわかること

  • Rust 2024エディションで変わった主な点と、移行の基本手順
  • 大規模ワークスペースで移行を安全に進める進め方
  • async Rust・WASM/WASI・FFIで現場が標準化しつつある運用の型
  • clippyやrustfmtをCI契約として扱う理由

Rust 2024が変えたこと

2025年2月20日にリリースされたRust 1.85.0で、Rust 2024エディションが安定化しました(公式発表)。エディションは言語の別バージョンではなく、クレートが明示的に選ぶルールセットです。2021エディションのクレートと2024エディションのクレートは、同じビルドグラフ内で共存できます。

Rustチームは2024エディションを「これまでで最大のエディション」と位置づけています。主な変更は次のとおりです。

  • asyncクロージャasync || {})が安定化。AsyncFn系トレイトもプレリュードに追加され、高階な非同期関数の型表現が書きやすくなりました
  • RPITのライフタイム捕捉が変更。use<..>がない場合、スコープ内のライフタイムが暗黙に捕捉されます
  • genキーワードの予約、マクロのexprマッチャー拡張、unsafe externブロックの必須化など、言語の厳格化
  • プレリュードにFutureIntoFutureを追加std::env::set_varなど一部APIのunsafe
  • Cargoのresolverrust-versionを考慮するようになり、依存解決の挙動が変わります

構文の目新しさより、チームが「stable 1.85以上」という共通基準を持てる点が実務への影響は大きいです。ナイトリー依存やツールチェーンのバラつきが減り、移行を期限付きのエンジニアリングタスクとして計画しやすくなりました。

移行手順:5ステップで進める

公式のエディション移行ガイド(The Rust Edition Guide)に沿った手順は次のとおりです。

  1. rustup update stableでツールチェーンを1.85.0以上に更新する
  2. cargo updateで依存クレートを最新化する
  3. cargo fix --editionで互換性のある修正を自動適用する
  4. Cargo.tomledition"2024"に変更する
  5. cargo buildまたはcargo testで検証し、cargo fmtで整形する

cargo fix --editionは挙動を変えない保守的な修正のみ行います。2024の新しいセマンティクスを意図的に取り入れたい場合は、自動修正の結果をそのまま採用する必要はありません。

大規模ワークスペースでは、Code and Bittersの事例(参考)のように、2021エディションのままrust-2024-compatibilityリントを先に有効化してからエディション切り替えを行う手法が有効です。bindgenやcxxなどコード生成系のproc-macroは、先に更新しておくとcargo fixの結果が読みやすくなります。

ワークスペース移行の進め方

移行で痛みが出やすいのは、エディション切り替えそのものより、マクロ多用クレート・リント放置・featureフラグの複雑化です。

実務では、リポジトリ直下にrust-toolchain.tomlを置き、ローカルとCIのツールチェーンを揃えます。移行の冒頭で次を実行するチームが多いです。

rustup update stable
cargo +stable fix --edition
cargo +stable fmt
cargo +stable clippy --all-targets --all-features

エディションはクレート単位で段階的に切り替えられます。リーフクレートから進めるか、トップレベルから進めるかは、mainブランチを常にグリーンに保てる方を選びます。数週間にわたる巨大なアップグレードブランチは、マージコンフリクトで変更の意味が不明瞭になりやすいため避けた方がよいです。

Cargoのresolver(依存グラフ上のfeature統合ルール)も見直し対象です。大規模リポジトリでは、featureフラグの意図を明示し、「全feature有効」のCIと「デフォルトfeature」のCIを分けると、環境差分によるビルドのブレを早期に検出できます。

async Rust:構文より運用設計

2026年のasync Rustの話題は、ランタイム争いより運用の成熟度に移っています。Tokioが多くのサービスで事実上の中心にあり、Axumのようなフレームワークはランタイムモデルを隠さずに読みやすいハンドラを書ける点で採用が進んでいます。

現場で標準化しつつあるのは次の方針です。

  • リクエストタイムアウト時のタスクキャンセル
  • 同時実行数の上限とバックプレッシャー
  • リトライポリシーと構造化ログ
  • テールレイテンシの計測

async fnの構文は単純ですが、Rustは運用モデルを自動で与えてくれません。チーム内でエラータイプ・メトリクス・非同期ポリシーを共通化する内部クレートを持つ動きが増えています。asyncクロージャの安定化は型表現の課題を減らしますが、ハングしたタスクや無制限なキュー増加の防止は、引き続き設計と計測の領域です。

WASMとWASI:サンドボックス単位としての選択肢

WebAssembly(Wasm)は、ネイティブバイナリをプラットフォームごとに配布する方式と、フルOSを前提とするコンテナの中間に位置する実行単位です。WASI(WebAssembly System Interface)は、Wasmモジュールがファイルやネットワークなど外部とやり取りするための標準インターフェースです。

2026年にはWASI 0.3.0が策定され、WebAssemblyコンポーネントモデルの非同期プリミティブに基づく形で安定版として承認されました(Bytecode Allianceの発表)。WASI 0.2でpollableinput-streamに頼っていた非同期処理が、コンポーネントモデル上のfuturestream型に整理され、インターフェース定義が簡潔になっています。

一方で、ランタイムやターゲットごとの対応状況には差があります。ポリシーエンジン、プラグイン、エッジ向けの変換モジュールなど、サンドボックスが要件の部分にWasmを置く判断が現実的です。システム全体をWasm化するより、境界を絞った利用の方が失敗しにくいです。

FFIとunsafe:小さな島に閉じ込める

RustをC/C++やプラットフォームSDKと組み合わせるプロジェクトでは、FFI(Foreign Function Interface、他言語との関数呼び出し境界)の設計が品質を左右します。関数をそのままバインドするだけでは、所有権やライフタイムのルールが境界を越えて破綻しやすく、本番でメモリ破壊につながります。

成熟したチームは、unsafeコードを小さなモジュールに集約し、不変条件(invariant、常に満たすべき前提条件)をコメントで明示します。安全なAPIだけをクレート外部に公開し、レビューとテストの対象を狭めます。Rust 2024ではunsafe externブロックの必須化やstatic mut参照の拒否など、unsafe周りの診断も強化されています。

CI運用:clippyとrustfmtを契約にする

本番Rustチームに共通するのは、ツールを「好み」ではなく「契約」として扱う姿勢です。

  • rustfmtをCIで実行し、フォーマット差分をビルド失敗にする
  • clippyをゲートとして通し、警告放置を防ぐ
  • ツールチェーンをrust-toolchain.tomlで固定し、再現可能なビルドを維持する
  • エディション移行・依存更新・ツールチェーン更新を定期メンテナンスとして計画する

移行直後にclippy警告が大量に出る場合、それはエディションが不安定なのではなく、これまで無視されていた技術的負債が可視化されたサインです。警告ポリシー(どこまで直すか、例外の扱い、ロールバック手順)をチームで合意しておくと、移行の「完了」定義が明確になります。

2026年に向けた判断基準

Rust 2024の安定化は、言語そのものの劇的な変化より、エコシステムの同期点として機能しています。インフラコンポーネント、高スループットAPI、エッジサービス、CLIツールなど、安全性と性能がビジネス要件に直結する領域では、Rustの採用理由が明確です。

一方、SaaS APIの接着コードが中心で、組織の学習コストを払えない場合は、より単純なスタックの方が合理的です。Rustは「難しい言語」というより「厳格な言語」であり、厳格さの対価はインシデント削減・リソース効率・境界の明確化として回収できる場面で選ぶのがよいです。