2月21日、Rust Blogで「Rust 1.85.0 と Rust 2024 の発表(Announcing Rust 1.85.0 and Rust 2024)」と題した記事が公開された。この記事では、Rust 1.85.0の正式リリースと2024エディションの安定化について詳しく紹介されている。

以下に、その内容を簡潔にまとめて紹介する。
Rust 2024エディション
Rustにおけるエディションは後方互換性のリスクがある変更をオプトイン方式で導入する仕組みであり、今回の2024エディションは過去最大規模の更新となっている。言語からツールに至るまで幅広い変更が行われており、具体的な内容はエディションガイドを参照いただきたい。
Rust 2024エディションへの移行にあたっては、まずは「cargo fix」コマンドを利用するとよいだろう。既存プロジェクトにおいて修正が必要な点を提案してくれるプログラムだ。
必要な変更がほとんどないケースもあるが、自動修正が提案する変更はあくまで既存の動作を変えない保守的なものである点に留意する必要がある。
async
クロージャ
Rust 1.85.0ではasync || {}
という形で非同期クロージャを利用できるようになった。これにより、通常のクロージャ同様にローカル変数をキャプチャしながら非同期処理を行うことが可能である。加えて、新たに標準ライブラリのプリリュードに3つのトレイトAsyncFn
、AsyncFnMut
、AsyncFnOnce
が導入された。
従来は|| async {}
のように非同期ブロックを内包する方法で代用していたが、その場合クロージャがキャプチャした値をブロック内へ借用させるのは容易ではなかった。async
クロージャならこれが解決できる。以下の例では、ベクタvec
の要素を非同期に操作している。
let mut vec: Vec<String> = vec![];
let closure = async || {
vec.push(ready(String::from("")).await);
};
また、Fn
トレイトにおける高階ライフタイム境界(higher-ranked function signature)を満たすようなFuture
を返すことが困難だったが、AsyncFn
トレイトを使うことでその問題も解決できる。
use core::future::Future;
async fn f<Fut>(_: impl for<'a> Fn(&'a u8) -> Fut)
where
Fut: Future<Output = ()>,
{ todo!() }
async fn f2(_: impl for<'a> AsyncFn(&'a u8))
{ todo!() }
async fn main() {
async fn g(_: &u8) { todo!() }
f(g).await;
//~^ ERROR mismatched types
//~| ERROR one type is more general than the other
f2(g).await; // ok!
}
コンパイラ診断メッセージから特定のトレイト実装を非表示にする
新たに#[diagnostic::do_not_recommend]
属性が導入され、誤解を招くおそれのあるトレイト実装をコンパイラの診断メッセージから非表示にできるようになった。たとえば次の例ではFoo
を実装していない型に対してBar
が実装されていない旨をエラー表示する際、impl<T: Foo> Bar for T {}
が原因として示される。しかし、多くのユーザにとってはFoo
を実装するという回避策が不要な場合もある。そのような場合は次のように属性を付与するとよい。
#[diagnostic::do_not_recommend]
impl<T: Foo> Bar for T {}
これによってエラーでの提案が「MyType
にBar
が実装されていない」といったよりシンプルな内容に変わる。
タプルに対する FromIterator
と Extend
従来は (T, U)
の2要素タプルに関してFromIterator
やExtend
が利用できたが、Rust 1.85.0ではこの機能が1要素((T,)
)から12要素のタプルにまで拡張された。以下のように、一度のイテレータ操作で複数のコレクションへ要素を振り分けることができる。
use std::collections::{LinkedList, VecDeque};
fn main() {
let (squares, cubes, tesseracts): (Vec<_>, VecDeque<_>, LinkedList<_>) =
(0i32..10).map(|i| (i * i, i.pow(3), i.pow(4))).collect();
println!("{squares:?}");
println!("{cubes:?}");
println!("{tesseracts:?}");
}
出力例:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
[0, 1, 8, 27, 64, 125, 216, 343, 512, 729]
[0, 1, 16, 81, 256, 625, 1296, 2401, 4096, 6561]
std::env::home_dir()
の仕様変更
std::env::home_dir()
はWindows環境でHOME
変数が設定されている場合、意図しない結果を返す可能性があることから長らく非推奨になっていた。今後はこの挙動をバグ修正として変更し、近い将来に非推奨指定も取り除く予定である。
その他の変更
Rust自体やCargo、Clippyに関する詳細な変更点は下記リンクを参照のこと。
詳細は[Announcing Rust 1.85.0 and Rust 2024」を参照していただきたい。