Rust 2024 Editionが2024年末にリリースされ、2025年から本格的に利用が広がっています。約3年ぶりのエディション更新となる今回は、言語の人間工学(ergonomics)を大きく向上させる機能が多数含まれています。本記事では、Rust開発者が押さえておくべき新機能と、既存プロジェクトの移行方法を解説します。
Rust Editionとは
Rustは後方互換性を重視しながらも、言語の進化を止めないために「Edition」という仕組みを採用しています。
Rust Edition の歴史:
├── Rust 2015 (1.0) - 初期リリース
├── Rust 2018 (1.31) - async/await, NLL導入
├── Rust 2021 (1.56) - IntoIterator改善, Disjoint capture
└── Rust 2024 (1.85) - 今回のリリース
重要: 異なるEditionのクレートは相互に依存可能です。Editionはソースコード解釈の変更であり、ABIやセマンティクスの破壊的変更ではありません。
主要な新機能
1. RPIT(impl Trait in return position)のライフタイムキャプチャ変更
Rust 2024では、impl Traitの戻り値型が自動的にすべてのライフタイムパラメータをキャプチャするようになりました。
// Rust 2021以前 - 明示的なライフタイム指定が必要
fn process_2021<'a>(data: &'a str) -> impl Iterator<Item = &'a str> + 'a {
data.split(',')
}
// Rust 2024 - 自動キャプチャ
fn process_2024(data: &str) -> impl Iterator<Item = &str> {
data.split(',') // ライフタイムが自動的にキャプチャされる
}
キャプチャを明示的に制御したい場合は、新しい use<> 構文を使用します。
// 特定のライフタイムのみキャプチャ
fn selective_capture<'a, 'b>(
x: &'a str,
y: &'b str
) -> impl Iterator<Item = &'a str> + use<'a> {
x.split(',') // 'a のみキャプチャ、'b はキャプチャしない
}
2. gen キーワードとジェネレータ
genが予約キーワードとなり、将来のジェネレータ機能に備えています。
// 将来のバージョンで利用可能になる予定の構文
gen fn fibonacci() -> impl Iterator<Item = u64> {
let (mut a, mut b) = (0, 1);
loop {
yield a;
(a, b) = (b, a + b);
}
}
// 使用例(将来のRust)
for num in fibonacci().take(10) {
println!("{}", num);
}
現時点で gen を識別子として使用している場合は、r#gen に変更が必要です。
3. unsafe_op_in_unsafe_fn デフォルト有効化
unsafe関数内でも、unsafe操作には明示的なunsafeブロックが必要になりました。
// Rust 2021以前
unsafe fn old_style(ptr: *const i32) -> i32 {
*ptr // unsafe操作だが、ブロック不要だった
}
// Rust 2024
unsafe fn new_style(ptr: *const i32) -> i32 {
// unsafe操作には明示的なブロックが必要
unsafe { *ptr }
}
この変更により、unsafe関数内のどの操作が実際にunsafeなのかが明確になり、コードレビューが容易になります。
4. unsafe extern ブロック
外部関数のunsafe性を明示的に宣言できるようになりました。
// Rust 2024 - より明示的な宣言
unsafe extern "C" {
// すべての関数がunsafe
fn system_call(id: i32) -> i32;
fn read_memory(ptr: *const u8, len: usize) -> i32;
// 安全な関数には safe キーワード
safe fn get_errno() -> i32;
}
fn main() {
// system_callはunsafeブロック必須
let result = unsafe { system_call(42) };
// get_errno()は直接呼び出し可能
let errno = get_errno();
}
5. 予約語の追加
将来の言語機能のため、以下のキーワードが予約されました。
| キーワード | 用途(予定) | 回避策 |
|---|---|---|
gen | ジェネレータ | r#gen |
try | try-catch構文 | r#try |
// 移行前
let gen = 42;
let try = "attempt";
// 移行後
let r#gen = 42;
let r#try = "attempt";
6. Never型(!)のフォールバック変更
!型(never型)のフォールバック動作が () から ! 自体に変更されました。
// この変更が影響するケース
let value = loop {
if condition {
break 42;
}
// 到達不能な場合の型推論が変化
};
7. マクロフラグメント指定子の厳格化
expr フラグメント指定子の動作が変更されました。
macro_rules! example {
// Rust 2021: exprは const {} や if {} などを受け入れない場合があった
// Rust 2024: expr は expr_2021 の動作
($e:expr) => { ... };
// 新しい指定子
($e:expr_2021) => { ... }; // 従来の動作
}
プロジェクトの移行方法
Step 1: Rust ツールチェーンの更新
# 最新のstableへ更新
rustup update stable
# バージョン確認(1.85.0以上)
rustc --version
Step 2: 自動移行の実行
# 移行の事前チェック
cargo fix --edition --allow-dirty
# Cargo.tomlのedition更新
# edition = "2021" → edition = "2024"
Step 3: Cargo.toml の更新
[package]
name = "my-project"
version = "0.1.0"
edition = "2024" # 2021 から変更
rust-version = "1.85" # MSRV も更新推奨
[dependencies]
# 依存クレートはそのままで動作(edition互換性)
Step 4: 手動修正が必要なケース
// 1. gen/try キーワードの使用箇所
- let gen = Generator::new();
+ let r#gen = Generator::new();
// 2. unsafe関数内のunsafe操作
unsafe fn example() {
- dangerous_operation();
+ unsafe { dangerous_operation(); }
}
// 3. extern ブロック
- extern "C" {
+ unsafe extern "C" {
fn c_function();
}
新機能の活用例
パターンマッチングの改善
// if-let チェーンの改善
fn process_option(opt: Option<Result<i32, Error>>) {
if let Some(Ok(value)) = opt
&& value > 0
&& is_valid(value)
{
println!("Valid positive value: {}", value);
}
}
// let-else の活用(2021から利用可能、2024でも推奨)
fn get_config() -> Config {
let Some(path) = env::var_os("CONFIG_PATH") else {
return Config::default();
};
let Ok(content) = fs::read_to_string(&path) else {
eprintln!("Failed to read config file");
return Config::default();
};
toml::from_str(&content).unwrap_or_default()
}
より安全なunsafeコード
/// Rust 2024での推奨パターン
///
/// # Safety
/// - `ptr` は有効なメモリを指していること
/// - `len` はバッファサイズを超えないこと
pub unsafe fn copy_from_raw(ptr: *const u8, len: usize) -> Vec<u8> {
let mut result = Vec::with_capacity(len);
// 各unsafe操作を個別にドキュメント可能
unsafe {
// SAFETY: 呼び出し元がptrの有効性を保証
std::ptr::copy_nonoverlapping(ptr, result.as_mut_ptr(), len);
}
unsafe {
// SAFETY: copy_nonoverlappingで初期化済み
result.set_len(len);
}
result
}
エコシステムの対応状況
主要クレートの対応
| クレート | Edition 2024 対応 | 備考 |
|---|---|---|
| tokio | 対応済み | 1.40+ |
| serde | 対応済み | 1.0.200+ |
| clap | 対応済み | 4.5+ |
| anyhow | 対応済み | 1.0.90+ |
| thiserror | 対応済み | 2.0+ |
IDE サポート
- rust-analyzer: 完全対応
- IntelliJ Rust: 対応済み
- VS Code: rust-analyzer拡張で対応
パフォーマンスと安定性
Rust 2024 Editionでは、コンパイラの最適化も進んでいます。
コンパイル時間の改善(大規模プロジェクト):
├── インクリメンタルビルド: 約15%高速化
├── 並列フロントエンド: デフォルト有効
└── リンク時間: ThinLTO最適化の改善
まとめ
Rust 2024 Editionは、言語の安全性と人間工学を両立させる重要なアップデートです。
主要な変更点
- ライフタイムの自動キャプチャ: より直感的なコード記述
- unsafe の明示化強化: 安全性の可視化向上
- 予約語の追加: 将来のジェネレータ機能への準備
- マクロの厳格化: より予測可能なマクロ展開
移行のポイント
cargo fix --editionで大半は自動修正可能- unsafe関数内のunsafe操作は手動確認推奨
- 依存クレートのEditionは気にしなくてOK
既存プロジェクトの移行は比較的スムーズに行えますので、新しいEditionの恩恵を受けるために早めの移行をお勧めします。