本文へスキップ

Rust 1.99がC-variadic関数の定義を安定化

2026年10月1日に公開されたRust 1.99.0により、安定版のRustでprintfのようなC-variadic関数、つまり可変長引数(バリアディック)関数を定義できるようになりました。LLVM 23に移行し、ジェネリクスへのno_mangleはエラーになります。

著者 Tech AI Wire Team

4 分で読めます

Rust Blogの記事「Announcing Rust 1.99.0」のスクリーンショット。2026年10月1日付、Rust Release Teamによる投稿。

数字で見る

new code-generation backend
LLVM 23
average Rustdoc speedup on trait impl filtering
20%
best-case Rustdoc speedup on some crates
40%
release that first warned about no_mangle on generics
1.56

Rustチームは2026年10月1日、Rust 1.99.0をリリースしました。目玉となる変更は、安定版のRustでC-variadic関数を定義できるようになったことです。これは、Cのprintfのように任意の数の引数を受け取る種類の関数です。これにより、Cと密接に連携しなければならないRustコードにとっての穴が埋まります。

このリリースではほかにも、コンパイラーがLLVM 23に移行し、ドキュメントツールが高速化され、長年続いてきた警告の1つがハードエラーに変わります。

C-variadicの定義で何が加わるか

可変長引数関数(variadic function)は、可変個の引数を受け付けます。Cでは広く使われており、Rustも以前からそれらを呼び出すことができました。しかし、Rustで定義するのは別の話でした。公式の告知にはこうあります。「Rustはすでに、外部で定義された可変長引数関数(例:libc::printf)を呼び出すことができました。Rust 1.99では、これらの関数をRust自体で書けるようになりました」。

構文では、最後のパラメーターに...を使います。ByteIOTAは、定義の形をunsafe extern "C" fn my_logger(count: u32, mut args: ...) -> i32と示しています。関数の内部では、追加の引数はcore::ffi::VaListとして渡されます。Rustのブログによると、これはバイナリレベルでCのva_list型と互換性があります。Linux Compatibleによると、コードはnext_arg::<T>()で各引数を読み取ります。

VaArgSafeというトレイトが、どの型を渡せるかを管理します。このトレイトは引数リストから安全に読み取れる型を示し、型の不一致を防ぐのに役立ちます。Rustのブログとreleases.rsによると、このリリースではnaked関数でも可変長引数のシグネチャーを使えるようになりました。naked関数とは、コンパイラーがセットアップコードなしで出力する関数です。低レベルのコードや組み込み向けのコードは、呼び出し規約を厳密に制御するためにこれを使います。

新たに安定化したライブラリーAPI

Rustのブログが、安定版で新たに使えるようになったAPIとして挙げているものには、次が含まれます。

  • メモリーレイアウト:Layout::for_value_raw、mem::size_of_val_raw、mem::align_of_val_raw
  • コレクションとBox:Box::into_non_null、Vec::into_parts、Vec::from_parts、VecDeque::retain_back
  • ファイルシステム:std::fs::set_times、std::fs::set_times_nofollow

set_times関数は、標準ライブラリーからファイルのタイムスタンプを変更します。名前が示すとおり、_nofollow版はシンボリックリンクをたどりません。

コンパイラー、プラットフォーム、ツールの変更

Rust 1.99はLLVM 23にアップグレードされます。LLVMは、Rustをマシンコードに変換するコード生成ライブラリーです。ByteIOTAによると、ベンチマーク全体でコンパイルにかかる実時間が平均1.2%短縮されました。これは、2か月間で得られた4.57%の改善の一部です。

Linux Compatibleとreleases.rsによる、そのほかの変更は次のとおりです。

分野変更
プラットフォームmuslを使うRISC-V 64ビットLinuxが、Tier 2サポートに昇格
リンクGNUとmuslのターゲットで、静的な位置独立実行ファイルが有効に
Rustdocトレイト実装の絞り込みが平均で約20%、一部のクレートでは最大40%高速化
マクロ属性マクロが、#[my_macro] mod foo;のような別ファイルのモジュール(outlined module)でも使えるように
インラインアセンブリーx86で、128ビット整数をベクトルレジスターで渡せるように

RustのビルドツールであるCargoには、3つの変更があります。新しいdebugプロファイルが予約されます。releases.rsはこれを、devプロファイルをデバッグ向けから切り離し、「より妥当なデフォルトにする」ための準備だと説明しています。また、環境変数CIが設定されていると、インクリメンタルコンパイルが無効になります。ByteIOTAによると、CARGO_INCREMENTAL=1で再び有効にできます。2024エディションのワークスペースメンバーは、継承した依存関係のデフォルトを上書きすることもできます。

何が壊れる可能性があるか

このリリースには、互換性に関わる変更がいくつか含まれます。

変更詳細
ジェネリックな項目への#[no_mangle]ハードエラーに。ByteIOTAによると、Rust 1.56から警告が出ていた
従来の整数型モジュール完全に非推奨に
extern staticByteIOTAによると、借用が自動的に'staticへ昇格しなくなった
ドキュメントコメント内のコードブロックその中の属性には有効な対象が必要。なければドキュメントのビルドが失敗する
RangeInclusive反復処理の最適化が進み、すでに使い切った範囲の動作が変わる
Pin::new_unchecked安全性の規則がより厳密に明文化された

これは、この言語にとって忙しい1年の最新の一歩です。8月には、Rustが10年越しにnever型を安定化し、Nightlyビルドでは次世代トレイトソルバーが有効化されました。

これが開発者にとって意味すること

printfのシムは削除しましょう。Cの呼び出し元から可変長引数を受け取るためだけに、Cのコードを書いたりNightlyの機能を使ったりしていたなら、今は安定版のRustでそれができます。プラグインホスト、カスタムアロケーター、ロギングのブリッジが、まず確認すべき場所です。

アップグレードの前に、ジェネリックなコードに#[no_mangle]がないか確認しましょう。Rust 1.56から警告が出ていたため、その警告が出たままコンパイルできていたクレートは、今後は失敗します。コードベースとベンダリングした依存関係で、ジェネリック関数に付いたこの属性を検索してください。

CIのビルド時間に注意しましょう。Cargoは今後、CIが設定されているとインクリメンタルコンパイルを無効にします。クリーンビルドでは通常それが正しい判断ですが、実行のたびにtargetディレクトリーをキャッシュして引き継ぐCI構成では、遅くなる可能性があります。自分で計測した時間がそれを示すなら、CARGO_INCREMENTAL=1を設定してください。

ドキュメントテストを実行しましょう。ドキュメントコメント内のコードブロックに古い属性が残っていると、ドキュメントのビルドが失敗するようになりました。壊れたサンプルがリリースを妨げないよう、早めにcargo test --docを実行してください。

使い終わった範囲を再利用するコードをテストしましょう。RangeInclusiveの変更が影響するのは、すでに最後まで反復された範囲だけです。ループの後もそうした範囲を使い続けるコードは、新しい動作に照らして確認すべきです。

出典

  1. Announcing Rust 1.99.0 - Rust Blog
  2. Rust 1.99.0 Ships with Stable C-Variadic Functions - Linux Compatible
  3. Rust 1.99 Is Out: C-Variadics and What Breaks - ByteIOTA
  4. 1.99.0 - releases.rs

関連記事

A terminal window showing a C++ project being linked with mold, with the elapsed link time visible in the output.
開発ツール

moldのRust書き換え、Linuxの標準リンカを目指す

moldはLLVMのlldより中央値で4.9倍速くリンクします。作者はこれをRust(ラスト)で書き直し、ディストリビューションに/usr/bin/ldとして採用させることを狙っています。