本日8/25(金)にリリースされたRust 1.72の変更点を詳しく紹介します。 もしこの記事が参考になれば記事末尾から活動を支援頂けると嬉しいです。
ピックアップ
個人的に注目する変更点を「ピックアップ」としてまとめました。 全ての変更点を網羅したリストは変更点リストをご覧ください。
rustfmtがlet-elseに対応した
2022年11月3日にリリースされたRust 1.65から使えるようになったlet-else文(let Some(x) = x else { return };みたいなやつ)ですが、
rustfmtが対応していなかったため、これまでは手動で何となく整形をしていました。
Rust 1.72に付属するrustfmtではこのlet-else文に対応し、ちゃんと一貫性のあるルールでコードが整形されるようになりました。
対応に10ヶ月近く掛かった理由についてはRust Blogにあります。 まあまあ長い英語記事なので分かりやすいよう一段落に要約しておきます。
なお現在は新しい永続的なスタイルチームが発足しており、また実験的な構文についてもrustfmtへの実装ができることになっているため、 今後はlet-elseのように時間が掛かることはないと思われます。
使えない型などの#[cfg]情報が出るようになった
#[cfg(feature = "...")] pub struct X;といった形で定義されているアイテムを使うとした際、
コンパイルエラーに#[cfg]の情報が出るようになりました。
例えばserdeを使うとき、自動導出マクロのserde::{Deserialize, Serialize}を使うためにはCargo.tomlにfeatures = ["derive"]の指定が必要です。
ここで指定を忘れたとき、Rust 1.72からは以下のようなエラーが出るようになります。
error[E0433]: failed to resolve: could not find `Serialize` in `serde`
--> src/main.rs:1:17
|
1 | #[derive(serde::Serialize)]
| ^^^^^^^^^ could not find `Serialize` in `serde`
|
note: found an item that was configured out
--> /home/saito/.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde-1.0.185/src/lib.rs:322:37
|
322 | pub use serde_derive::{Deserialize, Serialize};
| ^^^^^^^^^
= note: the item is gated behind the `serde_derive` feature
なおserdeのコード上は#[cfg(feature = "serde_derive")]と指定されているため、
メッセージにはderiveではなくserde_deriveと表示されていることに注意してください。
メッセージに従って機能名(featuresの値)を指定すると予期せぬ動作になることもあり得るため、
機能名はREADME等文書を確認して指定しましょう。
終了済み子プロセスを死なせても成功するようになった
std::process::Childのkillメソッドが、既に終了しているプロセスに対してはエラーを返さなくなりました。
これまでは終了済みプロセスに対してはInvalidInputやPermissionDeniedが返っていたようですが、
TOCTOUを引き起こし得る挙動だったので少し使いやすくなったのではないでしょうか。
最近のrust-analyzer
最近rust-analyzerに入った変更の中から、個人的に気になったものをピックアップしました。
未使用インポートを削除できるようになった
2023-08-07(v0.3.1615)での変更です。
コードアクションを使ってuse文から未使用のモジュールを削除できるようになりました。
長い間待ち望まれていた機能ではないでしょうか。
ただしこのコードアクションはそれぞれの文に対して使用できるものであることに注意が必要です。 すべての未使用インポートを削除するには、コード全体またはインポート文全体を選択してからコードアクションを選択すると良いでしょう。
安定化されたAPIのドキュメント
安定化されたAPIのドキュメントを独自に訳して紹介します。リストだけ見たい方は安定化されたAPIをご覧ください。
String::leak
impl String { #[stable(feature = "string_leak", since = "1.72.0")] #[inline] pub fn leak<'a>(self) -> &'a mut str { /* 実装は省略 */ } }
Stringを消費してリークさせ、内容への可変参照&'a mut strを返す。
呼び出し側は戻り値のライフタイムを('static含め)自由に選べる。
戻り値の参照をドロップさせるとメモリリークを引き起こすため、
実際のところこの関数はプログラムの余命中存在するデータに使うのが理想的である。
これはStringの再確保や縮小を行わないため、
リークされたメモリ割り当てには戻されるスライスの一部ではない未使用の領域が含まれる可能性がある。
そうしたくない場合、into_boxed_strを呼び出してからBox::leakを呼び出すこと。
サンプル
簡単な使い方
let x = String::from("バケツ"); let static_ref: &'static mut str = x.leak(); assert_eq!(static_ref, "バケツ");
変更点リスト
言語
- 定数評価の制限をリントで置き換えて指数関数的後退(exponential backoff)の警告を追加
- 展開:クレートのてっぺんにおける
#![cfg(FALSE)]の挙動を変更 - LoongArch64向けにインラインアセンブリを安定化
- リント
clippy::undropped_manually_dropsを昇格 - リント
clippy::invalid_utf8_in_uncheckedをinvalid_from_utf8_unchecked及びinvalid_from_utf8昇格 - リント
clippy::cast_ref_to_mutをinvalid_reference_castingとして昇格 - リント
clippy::cmp_nanをinvalid_nan_comparisonsとして昇格 - 解決:人為的なインポートの曖昧性エラーを排除
dyn Traitなオブジェクトにおいて関連型にSelf: Sized境界を要求しない
コンパイラ
- 診断機能で言及するために
cfgで除外された項目の名前を記憶 - WASM固有の例外に対応
※訳注:バイナリサイズが膨れることから既定の挙動は変わっていない。これを有効化する手順はリンク先Issueを参照 - NetBSD/aarch64-be(ビッグエンディアンなarm64)に対応
- 出力ファイルに
-が指定された場合は標準出力に書き込み - 静的バイナリをリンクする際に、すべての固有ライブラリが静的にリンクされるよう強制
loongarch64-unknown-none*をTier 3ターゲットとして追加-C panic=abortの時に.eh_frameが出力されるのを抑止- デバッグ情報のコード生成で128ビットの列挙型バリアントに対応
- コンパイラ:tsan対応を有効化するようsolaris、illumosを更新
Rustのティア付けされたプラットフォーム対応の詳細はPlatform Supportのページ(※訳注:英語)を参照
ライブラリ
thread::{park, unpark}のメモリオーダリングを文書化- io:io::Write::writeにおける「最大1回の書き込み試行」要件を緩和
- HashSet::insertの挙動を規定
※訳注:既存の値が上書きされないことが保証されるようになった BufReader<T>、BufWriter<T>とLineWriter<T>におけるT: Sized境界を緩和select_nth_unstableの実行時保証を更新- プロセスを死なせる際、既に終了済みなら
Okを返す - 異なるアロケータ間でも
VecにPartialOrdを実装 - TypeIdのハッシュに128ビットを使用
- いくつかのコレクションにおけるDrainFilterでdrain-on-dropをしない
{Arc,Rc,Weak}::ptr_eqでポインタのメタデータを無視
Rustdoc
安定化されたAPI
以下のAPIが定数文脈で使えるようになった。
Cargo
-Zdoctest-in-workspaceを既定で有効化。それぞれの文書化テストを実行する際、 テストが所属するパッケージのルートディレクトリに作業ディレクトリを設定。 文書 #12221 #12288- 以前設定された
build.jobsの並列度を既定値に戻すための「default」キーワードへの対応を追加 #12222
互換性メモ
- IPv4互換アドレス向け
DisplayforIpv6Addrを変更 - Cargoにおける機能(feature)名の妥当性確認をコンパイルエラーに変更。 この警告はRust 1.49で追加された。これらの拡張文字はcrates.ioでは許可されていないため、 それ以外のレジストリのユーザーやレジストリに公開しない人にのみ影響するはずである。 #12291
関連リンク
さいごに
次のリリースのRust 1.73は10/6(金)にリリースされる予定です。 Rust 1.73ではパニック時の文言が変わったりするようです。