「Rust 1.85.0」公開 「Rust 2024エディション」は安定版に エディションの移行方法は?:言語、標準ライブラリの機能が複数改善
オープンソースのプログラミング言語「Rust」を開発するRustプロジェクトは、Rustの最新バージョンとなる「Rust 1.85.0」を発表した。最新の機能追加や変更を含む「Rust 2024エディション」が安定版になった。
オープンソースのプログラミング言語「Rust」を開発するRustプロジェクトは2025年2月20日(米国時間)、Rustの最新バージョンとなる「Rust 1.85.0」を発表した。
旧バージョンのRustをrustupコマンドで導入している場合、以下のコマンドを実行することで、Rust 1.85.0を入手できる。
$ rustup update stable
Rust 1.85.0のハイライトは以下の通り。
Rust 1.85.0のハイライト
「Rust 2024エディション」が安定版に 移行方法は?
Rustでは、後方互換性を保ちつつ、新しい機能や変更となる「破壊的変更」を加えることを目的に、「エディション」と呼ばれる仕組みを導入している。エディションはオプトイン形式で3年に一度公開されており、Rust 2024エディションは、2015年、2018年、2021年に続く4回目のRustエディションとなる。
Rustプロジェクトは、2021エディションから2024エディションに移行する手順や、既存プロジェクトを新しいエディションに移行するガイドを公開している。それによると、多くの場合、cargo fixコマンドにより、必要な変更を自動的に反映させることが可能だという。
一方で、Rustプロジェクトは「cargo fixコマンドによる自動修正は、コードの意味や動作を変更しないよう非常に慎重に動作する点に留意する必要がある」と述べている。
「async」クロージャ
Rustは、「async || {}」のような、呼び出されたときに「Future」を返す非同期クロージャをサポートするようになった。通常の関数とクロージャの違いに似て、非同期クロージャはローカル環境から値をキャプチャーできる「async fn」のように動作する。これに伴い、標準ライブラリのPreludeには3つの対応するトレイト(「AsyncFn」「AsyncFnMut」「AsyncFnOnce」)が追加されている。
幾つかのケースでは、通常のクロージャと非同期ブロックを組み合わせることで、「|| async {}」に近似した表現が既にできていた。だが、内側の非同期ブロックがクロージャによるキャプチャから借用を行うことはできない。これに対して、非同期クロージャでは次のように動作する。
let mut vec: Vec<String> = vec![]; let closure = async || { vec.push(String::from("")).await; };
また「Fn」トレイトが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]」属性は、アノテーションされたトレイト実装を診断メッセージの一部として表示しないよう、コンパイラに指示するものだ。ライブラリの作者にとって、ユーザーに対して有益でない、または誤解を招く可能性のある提案をコンパイラが行わないよう制御する手段になるという。
「FromIterator」と「Extend」の機能拡張
過去のRustバージョンでは、「(T, U)」形式のタプルペアのイテレータに対し、「Iterator::unzip」のような振る舞いを提供するための便利なトレイトとして、「FromIterator」および「Extend」が実装されてきた(Extendはバージョン1.56で、FromIteratorは1.79で追加されている)。
これらのトレイトが、より長いタプルに拡張され、単一要素「(T,)」から最大12要素「(T1, T2, .., T11, T12)」まで対応するようになった。例えば「collect()」を使用して一度に複数のコレクションに同時に要素を振り分ける操作が可能になる。
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」環境変数が設定されている場合(これは通常のWindowsの設定とは異なる)、予期しない結果を返す可能性があったためだ。
この問題を修正するため、関数の動作が更新された。これに続く今後のリリースにおいて、非推奨指定は解除される見込みだという。
言語、標準ライブラリの機能改善
その他、言語や標準ライブラリなど、以下のような複数の新機能追加、機能改善が行われている。
言語
- RPIT(Return Position Impl Trait)のライフタイムキャプチャールールの変更:「use<..>」が存在しない場合の「impl Trait」型によるパラメーターのデフォルトキャプチャー方法を変更した
- 「if let」の一時変数スコープの変更:「if let」式における一時変数のスコープを変更した
- ブロック内の末尾式の一時変数スコープの変更:ブロック内の末尾式の一時値のスコープを変更した
- matchエルゴノミクスの予約:混乱を避け、将来の改善を可能にするため、特定のパターンの組み合わせを禁止した
- 「extern」ブロックがunsafeに:「extern」ブロックは、「unsafe」の記述が必須となった
- Unsafe属性:「export_name」「link_section」「no_mangle」属性は「unsafe」の記述が必要となった
- 「unsafe_op_in_unsafe_fn」警告:「unsafe_op_in_unsafe_fn」リントはデフォルトで警告を発するようになり、「unsafe」関数内での操作には、明示的な「unsafe {}」ブロックが必要になった
- 「static mut」への参照禁止:「static mut」への参照は、デフォルトでエラーとなる・Never型フォールバックの変更:Never型(「!」)の型強制の方法を変更した。「never_type_fallback_flowing_into_unsafe」リントレベルを「拒否」に変更した
- マクロフラグメント指定子:「macro_rules!」マクロ内の「expr」フラグメント指定子は「const」式と「_」式にもマッチするようになった
- マクロフラグメント指定子の欠落:「missing_fragment_specifier」リントがハードエラーとなり、フラグメント指定子のないマクロメタ変数を拒否するようになった
- 「gen」の予約:将来的なジェネレータブロックが追加されることを想定し、「gen」キーワードを予約した
- 予約された構文:将来的なガード付き文字列リテラルの構文変更に備えて、「#"foo"#」スタイルの文字列および「##」トークンを予約した
標準ライブラリ
- Preludeの変更:「Future」と「IntoFuture」をPreludeに追加した
- 「Box<[T]>」への「IntoIterator」実装:Box化されたスライスでのイテレータの動作を変更した
- 新たにunsafeとなる関数:「std::env::set_var」「std::env::remove_var」「std::os::unix::process::CommandExt::before_exec」をunsafe関数に変更した
Cargo
- Rust-version対応リゾルバ:デフォルトの依存関係解決の動作を変更し、「rust-version」フィールドを考慮するようになった
- テーブルおよびキー名の統一:古くなった「Cargo.toml」キーを削除した
- 未使用の継承されたデフォルト機能の拒否:ワークスペースの継承された依存関係における「default-features = false」の動作を変更した
Rustdoc
- Rustdocの統合テスト:Doctestが単一の実行ファイルに統合され、パフォーマンスが大幅に向上した
- Rustdocのネストした「include!」の変更:ネストされた「include!」ファイルの相対パスの挙動を変更した
Rustfmt
- スタイルエディション:「スタイルエディション」の概念を導入した。これにより、Rust エディションとは独立してフォーマットエディションを制御できるようになった
- フォーマットの修正:さまざまなシチュエーションでのフォーマットに関する多数の修正を反映した
- Raw識別子のソート:「r#foo」形式の識別子のソート方法を変更した
- バージョン番号のソート:数を含む識別子のソート方法を変更した
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
Rustの年次調査「State of Rust 2024」が明らかにする、Rustの利用状況と課題
Rustプロジェクトの調査チームは、プログラミング言語「Rust」の利用状況に関する年次調査「State of Rust 2024」の結果を発表した。Microsoft、安全で高効率のプログラミング言語として「Rust」を高く評価
Microsoft Security Response Center(MSRC)は、ソフトウェアのセキュリティ確保と効率性の両方の要件を満たす最も有望なシステムプログラミング言語の一つとして、「Rust」を高く評価した。メモリ破壊バグをそもそも作り込まないことでセキュリティを確保できるという。プログラミング言語「Rust」とは? "Hello, World!"で基本を押さえる
Rustはどのようなプログラミング言語なのでしょうか? 本連載のスタートとなる今回は、Rust言語の概略と、手元にRustの動作環境構築までを紹介します。導入で利用可能になるコマンドと、最初のHello, World!プログラムも取り上げます。