本日5/3(金)にリリースされたRust 1.78の変更点を詳しく紹介します。 もしこの記事が参考になれば記事末尾から活動を支援頂けると嬉しいです。
ピックアップ
個人的に注目する変更点を「ピックアップ」としてまとめました。 全ての変更点を網羅したリストは変更点リストをご覧ください。
トレイト未実装時のエラー文言を自由に変更できるようになった
#[diagnostic::on_unimplemented]
属性が安定化されました。
これは、例えばジェネリクスの境界でT: Trait
としている際にT
にTrait
を実装していない型を指定した場合に出てくるエラー文言を変更できるものです。
この属性はmessage
・label
・note
の3引数を取り、message
はエラーの主要な文言を、label
は値が何であるかを示す文言を、note
は注釈を意味します。
またnote
は複数回指定することが出来ます。
文言の中では{Self}
が使おうとした型の名前に展開されます。またジェネリクスを使用している場合は波括弧で括られた名前が実際の型名に展開されます。
例えば次のような定義をした場合・・・
#[diagnostic::on_unimplemented( message = "{Self}はプログラミング言語ではありません", label = "ここ", note = "`Language`はプログラミング言語を意味しており、自然言語ではありません", note = "ほにゃほにゃ", )] trait Language {} struct Rust; impl Language for Rust {} struct Japanese; fn hoge<T: Language>(_: T) {} fn main() { hoge(Rust); hoge(Japanese); }
次のようなエラーが出力されます。
error[E0277]: Japaneseはプログラミング言語ではありません --> src/main.rs:18:10 | 18 | hoge(Japanese); | ---- ^^^^^^^^ ここ | | | required by a bound introduced by this call | = help: the trait `Language` is not implemented for `Japanese` = note: `Language`はプログラミング言語を意味しており、自然言語ではありません = note: ほにゃほにゃ = help: the trait `Language` is implemented for `Rust` note: required by a bound in `hoge` --> src/main.rs:14:12 | 14 | fn hoge<T: Language>(_: T) {} | ^^^^^^^^ required by this bound in `hoge`
将来的には#[diagnostic::on_unimplemented]
以外の属性が#[diagnostic]
以下に導入される可能性があります。
最近のrust-analyzer
最近のrust-analyzerのコーナーは今回おやすみです。
安定化されたAPIのドキュメント
残念ながらRust 1.78で安定化されたAPIはありません。
変更点リスト
言語
#[cfg(target_abi = ...)]
を安定化#[diagnostic]
名前空間と#[diagnostic::on_unimplemented]
属性を安定化- トレイト中の非同期関数を具体的なシグネチャで実装可能にした
- NaNでのパターンマッチをコンパイルエラーにし、残りの
illegal_floating_point_literal_pattern
を削除 - static mut:可変参照を(スライスと配列だけでなく)任意の型で許容
- リント
invalid_reference_casting
を、参照の大きなメモリレイアウトへのキャストも含むよう拡張 - 排他レンジ後の単一な切れ目のためのリント
non_contiguous_range_endpoints
を追加 - 古いバージョンのwasm-bindgenの使用のためのリント
wasm_c_abi
を追加。 このリントはCargoを使用している場合のみ動作する - リント
indirect_structural_match
とpointer_structural_match
をRFCに適合するよう更新 PartialEq
でない型の定数によるパターンをコンパイルエラーに- リント
refining_impl_trait
を変種_reachable
・_internal
に分割 - 高階
where
境界内で関連型を使用した際の不要な型推論を除去 - 型推論における循環型の積極的な検出を緩和
trait Trait: Auto {}
:dyn Trait
からdyn Auto
へのアップキャストを許容
コンパイラ
- リント
INVALID_DOC_ATTRIBUTES
は既定で拒否 - 冗長な
use
検査の精度を向上 - 後方で定義される
macro_rules!
が見つからない場合に定義の移動を提案 - 整数からポインタ型へのtransmuteをnullへのgep(※訳注:getelementptr)に引き下げ
ターゲットへの変更
- Windowsのティア1ターゲットが最低でもWindows 10を要求
wasm32-wasip1
を(ホストツール抜きの)ティア2ターゲットとして追加wasm32-wasip2
をティア3ターゲットとして追加wasm32-wasi-preview1-threads
をwasm32-wasip1-threads
に名称変更arm64ec-pc-windows-msvc
をティア3ターゲットとして追加- Cortex-R52向けに
armv8r-none-eabihf
をティア3ターゲットとして追加 loongarch64-unknown-linux-musl
をティア3ターゲットとして追加
Rustのティア付けされたプラットフォーム対応の詳細はPlatform Supportのページ(※訳注:英語)を参照
ライブラリ
- Unicodeをバージョン15.1.0に更新し、テーブルを再生成
- align_offsetとalign_toを全事例で正しく動作するようにした
- PartialEq・PartialOrd:推移的チェーンでの期待される挙動を文書化
- 標準ライブラリがpanic=abortでビルドされている場合の中毒ガードを最適化
- pthreadの
RwLock
を独自実装に置き換え - 全プラットフォームのCondvarにUnwindSafeを実装
char::is_grapheme_extended
においてASCII向けの高速な分岐を追加
安定化されたAPI
impl Read for &Stdin
- いくつかの
std::error::Error
関連の実装で非'static
ライフタイムを許容 impl<Fd: AsFd>
の実装が?Sized
を取るように↓impl From<TryReserveError> for io::Error
以下のAPIが定数文脈で使えるようになった。
Cargo
- ロックファイルv4を安定化
※訳注:バグ修正であり機能的な変更はない - ロックファイル生成時に
rust-version
を尊重 - 設定値を自動検出して
--charset
を制御 target.<triple>.rustdocflags
に公式対応- 全域的なキャッシュデータの追跡を安定化
その他
互換性メモ
- デバッグ用アサートが有効の場合、多くの危険な事前条件検査をユーザーコードで実行するようにした。 この変更によりユーザーは自分のコード内での未定義動作を捕捉しやすくなるが、具体的に何が検査されるかは一般的に安定化されていない
- riscvがsplit_debuginfo=offのみに対応するようになった
impl Trait
で隠れた型の境界を一貫して検査- 高階型の等価性を部分型に依存しないよう変更
- 正規化された関数が呼び出されたとき、戻り値型に関する境界を追加で検査
- リント
arithmetic_overflow
のカバレッジを展開
内部の変更
これらの変更がユーザーに直接利益をもたらすわけではないものの、コンパイラ及び周辺ツール内部では重要なパフォーマンス改善をもたらす。
- LLVM 18に更新
x86_64-pc-windows-msvc
ではrustc
を1CGUでビルドx86_64-apple-darwin
ではrustc
を1CGUでビルドrun-make
V2インフラとrun_make_support
ライブラリを導入し2つのテストをサンプルとして移植- Windows:Condvar・MutexとRwLockをfutexにより実装
関連リンク
さいごに
次のリリースのRust 1.79は6/14(金)にリリースされる予定です。
Rust 1.79では式を強制的に定数として評価させるconst
ブロックや関連型での境界の記述、
汎用的なNonZero
型など久々に盛りだくさんな内容となりそうです。