本日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互換アドレス向け
Display
forIpv6Addr
を変更 - Cargoにおける機能(feature)名の妥当性確認をコンパイルエラーに変更。 この警告はRust 1.49で追加された。これらの拡張文字はcrates.ioでは許可されていないため、 それ以外のレジストリのユーザーやレジストリに公開しない人にのみ影響するはずである。 #12291
関連リンク
さいごに
次のリリースのRust 1.73は10/6(金)にリリースされる予定です。 Rust 1.73ではパニック時の文言が変わったりするようです。