2025年のRustで確認すべきこと
2025年2月20日、Rust 1.85と同時にRust 2024 Editionが安定版になりました。
RustのEditionは、言語を別物へ分裂させずに、互換性へ影響する変更をproject単位でopt-inする仕組みです。Rust 2018や2021のcrateと、Rust 2024のcrateは同じdependency graph内で利用できます。
2025年のRustで重要なのは、Editionの意味、toolchainの更新、既存projectを安全に移行する方法です。
Rust 2024 Editionとは
Cargo.tomlのeditionで、crateが利用するEditionを指定します。
[package]
name = "sample-app"
version = "0.1.0"
edition = "2024"
rust-version = "1.85"
edition = "2024"を使うには、Rust 1.85以降が必要です。rust-versionは、そのprojectが必要とする最小Rust version(MSRV)をCargoへ伝えるために利用できます。
Editionを更新しても、すべてのdependencyを同じEditionへ揃える必要はありません。
主な言語変更
Rust 2024には複数の互換性変更があります。代表例を整理します。
unsafe extern
foreign functionの宣言が安全かどうかは、Rust compilerだけでは確認できません。Rust 2024ではextern blockへunsafeが必要です。
unsafe extern "C" {
safe fn sqrt(value: f64) -> f64;
unsafe fn dangerous_operation(ptr: *mut u8);
}
個々のfunctionをsafeとして宣言する場合、その呼び出しがRust側の追加条件なしで安全であることを宣言者が保証します。
unsafeなattribute
no_mangle、export_name、link_sectionなど、program全体のsymbolやlinkへ影響するattributeは、Rust 2024でunsafe(...)として明示します。
#[unsafe(no_mangle)]
pub extern "C" fn exported_function() {}
構文を直すだけでなく、symbol名が衝突しないなど、安全性の前提を確認します。
temporary scope
if letやblock末尾の式で、一時値がdropされる時点に変更があります。多くのcodeは自動migrationで互換性を保てますが、lock guardやborrowの生存期間へ依存するcodeではdiffを確認します。
impl Traitのcapture rule
return-position impl Traitがgeneric parameterやlifetimeをcaptureする既定ruleが変わりました。必要なparameterを明示するuse<...> syntaxも利用できます。
libraryのpublic APIでimpl Traitを返している場合は、利用者側のlifetimeやauto traitへ影響しないか確認します。
async closure
Rust 1.85では、async || { ... }形式のasync closureが安定しました。
async fn fetch_all(urls: Vec<String>) {
let fetch_one = async |url: String| {
reqwest::get(url).await?.text().await
};
for url in urls {
match fetch_one(url).await {
Ok(body) => println!("{}", body.len()),
Err(error) => eprintln!("{error}"),
}
}
}
async closureは周囲の値をborrowでき、async callbackを受け取るAPIを表現しやすくします。利用するcrateが要求するtrait boundと、closureが値をborrowする期間を確認してください。
既存projectを移行する
移行は専用branchで行います。最初に現在のtestとtoolchainを記録します。
rustc --version
cargo --version
cargo test
次に自動migrationを実行します。
cargo fix --edition
このcommandは、現在のEditionのまま互換性を保つ修正を適用します。変更内容をreviewした後、Cargo.tomlをedition = "2024"へ更新します。
cargo check
cargo test
cargo clippy --all-targets --all-features
cargo fmt --check
workspaceではcrateごとにEditionを指定できます。一度に全crateを変更せず、dependencyの下位から段階的に進める方法もあります。
MSRVを決める
開発環境だけを最新版へ上げても、利用者やCIが同じversionとは限りません。
libraryでは、どのRust versionからsupportするかを決め、rust-versionへ記載します。applicationでも、production imageとCIのtoolchainを固定すると再現しやすくなります。次はrust-toolchain.tomlの例です。
[toolchain]
channel = "1.85.0"
components = ["rustfmt", "clippy"]
security fixを取り込むためにpoint releaseやstableを追従する運用もあります。完全固定と自動更新のどちらにするか、更新時のtest手順と合わせて決めます。
Rustを導入する判断基準
Rustはmemory safetyをcompile時に検査し、garbage collectorなしで動作する言語です。次のような要件で候補になります。
- memory safetyとpredictableなresource管理が重要
- native binaryやcommand-line toolを作る
- latencyやmemory使用量を制御したい
- CやC++と連携する
- WebAssembly targetを利用する
一方、短いscript、既存libraryを優先したdata分析、prototype速度が最重要な用途では、PythonやJavaScriptなどが適する場合があります。
「他言語より常に高速」「唯一の安全な選択肢」とは判断しません。実装時間、必要なlibrary、team経験、build時間、運用環境を含めて比較します。
導入を小さく始める
既存system全体を書き換えるより、境界の明確なtoolから試します。
- CLIやbatchなど独立した処理を選ぶ
- input・outputとerror formatを決める
- benchmark条件と正しさのtestを用意する
- logging・metrics・deploy方法を確認する
- teamでcode reviewとownershipのruleを決める
C/C++と連携する場合はFFI境界へunsafeを集め、安全なwrapperを作ります。unsafeを禁止するだけでなく、必要な箇所の前提をdocument化することが重要です。
Linux kernelでのRust
Rust supportはLinux 6.1でmainlineへmergeされました。Linux kernelの公式documentationは、Rustでdriverやabstractionを開発するための情報を公開しています。
これはLinux kernel全体がRustへ移行した、またはCが置き換えられたという意味ではありません。kernel本体はCを中心に開発され、Rust supportは利用可能な領域とtoolchain要件を段階的に整備しています。
まとめ
- Rust 2024 EditionはRust 1.85とともに2025年2月に安定化した
- Editionはcrate単位で選べ、異なるEditionと共存できる
unsafe extern、temporary scope、capture ruleなどを確認するcargo fix --editionの差分をreviewしてから移行する- 市場予測ではなく、要件・ecosystem・team・運用で採用を判断する
参考リソース
- Announcing Rust 1.85.0 and Rust 2024
- Rust Edition Guide
- The Rust Programming Language
- Rust for Linux documentation