Rust 1.87.0リリース

2025年5月15日に[Rust 1.87.0](https://blog.rust-lang.org/2025/05/15/Rust-1.87.0/)がリリースされました。リリースノートの内容を見てみます

## TL;DR

Rust 1.87.0の主な変更点:

- 安全なコードからの`std::arch`組み込み関数の呼び出しが可能に
- `Vec::with_capacity`が要求通りのメモリ確保を保証
- `ControlFlow`が`#[must_use]`属性を持つように
- Windows版で`advapi32`ライブラリとのリンクが変更
- 多数のAPI機能が`const`コンテキストで利用可能に
- プラットフォームサポートの変更（追加と削除）

## 安全なコードからも呼び出せる`std::arch`組み込み関数

Rustの標準ライブラリには`std::arch`モジュールがあり、CPUの特殊命令セットを利用するための低レベルな組み込み関数が提供されています。これまではこれらの関数は`unsafe`でしか呼び出せませんでしたが、1.87.0からはポインタを引数に取らない多くの関数が、適切なターゲット機能が有効になっている場合に安全なコードから呼び出せるようになりました。

例えば、x86/x86_64、ARM、RISCVなどのアーキテクチャ向けの多くの命令が安全に呼べるようになっています:

```rust
// AVX2機能が有効な場合、安全にSIMD命令を使える
#[target_feature(enable = "avx2")]
fn use_avx2_safely() {
    // 以前は unsafe ブロックが必要だったが、1.87.0からは直接呼び出せる
    let result = std::arch::x86_64::_mm256_add_epi32(/* ... */);
}
```

この変更により、既存のコードに`unused_unsafe`警告が表示される場合があります。これは古いコードが不要な`unsafe`ブロックを使用している可能性があるためです。

## `Vec::with_capacity`の動作保証

`Vec::with_capacity`メソッドが、常に指定された容量ちょうどのメモリを確保することが保証されるようになりました。これまでは実装の詳細として扱われていましたが、1.87.0からは明示的な動作保証となります。

つまり、以下のコードで必要な容量がちょうど確保されます:

```rust
let v = Vec::<i32>::with_capacity(10);
// 確実に10要素分のメモリが確保される
```

ただし、`Vec::capacity`が返す値は内部実装の詳細によって、`with_capacity`で指定した値と異なる場合があることにご注意ください。

## `ControlFlow`が`#[must_use]`属性を持つように

`std::ops::ControlFlow`型に`#[must_use]`属性が追加されました。これにより、`ControlFlow`の戻り値を無視すると警告が表示されるようになります:

```rust
use std::ops::ControlFlow;

fn example() {
    let x = 5;
    
    // 警告が表示される: unused `ControlFlow` that must be used
    if x > 10 { ControlFlow::Break(()) } else { ControlFlow::Continue(()) };
    
    // 正しい使い方
    let result = if x > 10 { 
        ControlFlow::Break(()) 
    } else { 
        ControlFlow::Continue(()) 
    };
    
    match result {
        ControlFlow::Continue(()) => println!("継続"),
        ControlFlow::Break(()) => println!("中断"),
    }
}
```

この変更は`ControlFlow`型の重要性を強調し、値が誤って無視されることを防ぎます。

## Windows版の`advapi32`ライブラリのリンク変更

Windows環境において、標準ライブラリが`advapi32`ライブラリとのリンクを行わなくなりました（win7ターゲットを除く）。これまでこの仮定に依存していたCライブラリなどのコードは、明示的に`advapi32`をリンクする必要があります。

例えば、以下のようにCライブラリを利用する場合:

```rust
#[link(name = "my_c_lib")]
extern "C" {
    fn my_function();
}

// もし my_c_lib が advapi32 に依存している場合、
// 明示的にリンクする必要がある
#[link(name = "advapi32")]
extern "C" {}
```

## 多数の機能が`const`コンテキストで利用可能に

様々な関数やメソッドが`const`コンテキストで使えるようになりました。主な例としては:

- `<*const T>::offset_from_unsigned`と`<*mut T>::offset_from_unsigned`
- `<*const T>::byte_offset_from_unsigned`と`<*mut T>::byte_offset_from_unsigned`
- `NonNull::offset_from_unsigned`と`NonNull::byte_offset_from_unsigned` 
- 様々な整数型の`cast_signed`、`cast_unsigned`などのメソッド
- `<[T]>::copy_from_slice`
- 多数の文字列関連メソッド
- ソケットアドレス関連のセッターメソッド

これにより、コンパイル時評価できるコードの範囲が広がり、よりパワフルな`const`関数を書けるようになります:

```rust
const fn example() -> [u8; 4] {
    let mut arr = [0u8; 4];
    // 1.87.0から const コンテキストでも使用可能
    arr.copy_from_slice(&[1, 2, 3, 4]);
    arr
}

const RESULT: [u8; 4] = example();
```

## プラットフォームサポートの変更

### 新しいターゲットの追加

- PlayStation 1向けのtier 3ターゲット: `mipsel-sony-psx`
- QNX Neutrino RTOS向けのtier 3 no_stdターゲット: `aarch64-unknown-nto-qnx710`と`x86_64-pc-nto-qnx710`
- UEFIターゲットがtier 2に昇格: `aarch64-unknown-uefi`、`i686-unknown-uefi`、`x86_64-unknown-uefi`

### 削除されたターゲット

- Linuxカーネルtier 3ターゲット (実際のカーネルでは使用されていなかった)

## その他の変更点

### 小さな改善

- `f32::to_be_bytes`, `f32::to_le_bytes`, `f32::to_ne_bytes`などのメソッドが`const`コンテキストで使用可能に
- `i32::count_ones`, `i32::count_zeros`などのビット操作メソッドが`const`コンテキストで使用可能に
- `Option::get_disjoint_mut`や`HashMap::get_disjoint_mut`など、複数の要素を同時に可変で取得するメソッドの追加
- `sync::Once::wait`および`sync::Once::wait_force`の追加

### 非推奨・削除された機能

- `Cargo.toml`内の`lib.plugin`キーのサポートが削除（Rustプラグインサポートは4年前に非推奨化）
- `wasm32-wasi`ターゲットを使用すると、`wasm32-wasip1`に切り替えるよう警告が表示される（2025年1月に`wasm32-wasi`は削除予定）
- `std::panic::PanicInfo`が`std::panic::PanicHookInfo`にリネーム（古い名前は非推奨化、1.82.0から警告表示）

## 最後に

より詳細な情報は[公式リリースノート](https://blog.rust-lang.org/2025/05/15/Rust-1.87.0/)や[リリース詳細ドキュメント](https://doc.rust-lang.org/stable/releases.html)をご覧ください。

---

参考リンク:
- [Rust 1.87.0 公式リリースノート](https://blog.rust-lang.org/2025/05/15/Rust-1.87.0/)
- [Rust リリース詳細ドキュメント](https://doc.rust-lang.org/stable/releases.html)
- [Rust 1.87.0 Contributors](https://thanks.rust-lang.org/rust/1.87.0/)