Rust 2024 Edition完全ガイド - 新機能と移行のポイント

2025.12.02

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
trytry-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は、言語の安全性と人間工学を両立させる重要なアップデートです。

主要な変更点

  1. ライフタイムの自動キャプチャ: より直感的なコード記述
  2. unsafe の明示化強化: 安全性の可視化向上
  3. 予約語の追加: 将来のジェネレータ機能への準備
  4. マクロの厳格化: より予測可能なマクロ展開

移行のポイント

  • cargo fix --edition で大半は自動修正可能
  • unsafe関数内のunsafe操作は手動確認推奨
  • 依存クレートのEditionは気にしなくてOK

既存プロジェクトの移行は比較的スムーズに行えますので、新しいEditionの恩恵を受けるために早めの移行をお勧めします。

参考リンク

← 一覧に戻る