Rust 1.96.0 リリース
(blog.rust-lang.org)- Rust 1.96.0 は
rustup update stableでインストールでき、今後のリリース検証には beta/nightly チャネルで参加可能 - 新しい
core::range::Range*型はIteratorの代わりに IntoIterator を実装し、Copyの実装が可能になっており、将来的には範囲構文の基本型になる予定 - assert_matches! と
debug_assert_matches!は、パターン不一致時に値のDebug表現も一緒に出力し、テスト失敗の診断を容易にする - WebAssembly ターゲットでは、
--allow-undefinedがデフォルトで渡されなくなり、未定義シンボル は import ではなくリンカーエラーになる - Cargo にはサードパーティレジストリ利用者向けの CVE-2026-5223 と
CVE-2026-5222の修正が含まれ、crates.io 利用者は影響を受けない
Rust 1.96.0 の主な変更点
-
アップデートとテストチャネル
- 既存の Rust を
rustupでインストールしているユーザーは、rustup update stableで Rust 1.96.0 を入手できる rustupがない場合は、Rust Web サイトのrustupインストールページ から導入でき、1.96.0 の詳細リリースノートも公開されている- 今後のリリース検証に参加するには、
rustup default betaまたはrustup default nightlyで beta/nightly チャネル を利用でき、バグは Rust issue tracker に報告可能
- 既存の Rust を
-
新しい
Range*型- 既存の
Rangeと関連するcore::ops型は、多くのユーザーがCopyを期待していたが、自身でIteratorを実装しているためCopyは実装されていなかった - 同じ型に
IteratorとCopyを同時に実装する方式は、Clippy が指摘する footgun であるため避けられていた - RFC3550 は、
Iteratorの代わりにIntoIteratorを実装する代替の範囲型を提案しており、この構造ではそれらの型がCopyも実装できる - 標準ライブラリでは
core::range::Range、core::range::RangeFrom、core::range::RangeInclusiveと関連 イテレータ が安定化された - 近い将来の Rust バージョンでは、
core::opsから再エクスポートされるcore::range::RangeFullとcore::range::RangeTo、そして現在の範囲型の新しい配置先となるcore::range::legacy::*も追加される予定 0..1のような 範囲構文 は現在レガシー型を生成するが、将来の edition ではcore::range型に切り替わる予定- 今回の安定化により、
startとendを分離しなくてもスライスアクセサをCopy型に保持できる - 例:
use core::range::Range; #[derive(Clone, Copy)] pub struct Span(Range<usize>); impl Span { pub fn of(self, s: &str) -> &str { &s[self.0] } } - 新しい
RangeInclusiveはフィールドを公開しており、レガシー版のように消費済みイテレータ状態の露出を避ける必要がない - 新しい型では反復を開始する前にまず変換が必要なため、公開フィールドは問題にならない
- ライブラリ作者は公開 API でレガシーと新しい範囲型の両方を受け取る
impl RangeBoundsの利用を検討すべき - 具体的な型が必要な場合は、将来のデフォルトになる 新しい範囲型 を優先することが推奨される
- 既存の
-
パターンマッチングアサーションマクロ
- 新しいマクロ
assert_matches!とdebug_assert_matches!は、値が指定パターンに一致するかを検査し、一致しなければその値のDebug表現付きで panic する - この 2 つのマクロは本質的には
assert!(matches!(..))、debug_assert!(matches!(..))と同じだが、失敗時に出力される値によって 診断しやすさ が向上する - 同名のマクロを提供する人気のサードパーティクレートと衝突する可能性があるため、標準プレリュードには追加されていない
- 使用前に
coreまたはstdから直接 import する必要がある - 例:
use core::assert_matches; /// [Random Number](https://xkcd.com/221/) fn get_random_number() -> u32 { // chosen by a fair dice roll. // guaranteed to be random. 4 } fn main() { assert_matches!(get_random_number(), 1..=6); }
- 新しいマクロ
-
WebAssembly ターゲットの変更
- WebAssembly ターゲットは、もはやリンカーに
--allow-undefinedを渡さない - リンク時の 未定義シンボル は
"env"モジュールの WebAssembly import に変換されず、リンカーエラーになる - リンク関連シンボルがすべて未定義ならモジュールはリンクされないため、バグをより早く発見でき、シンボル名などに起因する偶発的な問題も防げる
- 未定義のリンク関連シンボルは通常、ビルド時のバグまたは設定ミスを示す
- 既存の挙動が意図されたものである場合は、
RUSTFLAGS=-Clink-arg=--allow-undefinedで元に戻すか、ソースコードでシンボルを定義するブロックに#[link(wasm_import_module = "env")]を使える - この変更は 以前のブログ告知 の後、Rust 1.96 で適用された
- WebAssembly ターゲットは、もはやリンカーに
安定化 API とセキュリティ修正
-
安定化された API
-
Cargo セキュリティ勧告 2 件
- Rust 1.96 には、サードパーティレジストリ利用者向けの Cargo 脆弱性 2 件 の修正が含まれる
- CVE-2026-5223 は、シンボリックリンクを含むクレート tarball の展開に関する 中程度の深刻度 の脆弱性
- CVE-2026-5222 は、正規化された URL を通じた認証に関する 低い深刻度 の脆弱性
- crates.io 利用者は、どちらの脆弱性の影響も受けない
-
追加の変更点
1件のコメント
Lobste.rsの意見
assert_matchesは欲しくなることが多く、そのたびに新しいクレートを追加するか自分で再実装するか悩んでいたので、標準ライブラリに入るのはうれしい範囲を
Copy型 にしようとしている段階が気に入っている 範囲を複製しなければならず驚いたことがたまにあったし、12..34は小さくてコピー可能なデータであるべきだという直感にもより合っている ただ、同じ名前の型がいくつもできると、VS Code が次にuse宣言を自動追加するときに間違った型を持ってきてしまわないか少し心配だ