2025年5月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などのアーキテクチャ向けの多くの命令が安全に呼べるようになっています:
// 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からは明示的な動作保証となります。
つまり、以下のコードで必要な容量がちょうど確保されます:
let v = Vec::<i32>::with_capacity(10);
// 確実に10要素分のメモリが確保される
ただし、Vec::capacity
が返す値は内部実装の詳細によって、with_capacity
で指定した値と異なる場合があることにご注意ください。
ControlFlow
が#[must_use]
属性を持つように
std::ops::ControlFlow
型に#[must_use]
属性が追加されました。これにより、ControlFlow
の戻り値を無視すると警告が表示されるようになります:
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ライブラリを利用する場合:
#[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
関数を書けるようになります:
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から警告表示)
最後に
より詳細な情報は公式リリースノートやリリース詳細ドキュメントをご覧ください。
参考リンク: