NewsOpen SourceProgramming Languages

Rust 1.98 Stable: C-Variadic Functions, PartialOrd Fix, August 20

Rust 1.98.0 goes stable on August 20. It’s been in beta since July 3, and compared to 1.97 — which flipped symbol mangling defaults and shipped new integer bit methods — this one reads quieter at first glance. It isn’t. Rust 1.98 closes two of the longest-standing gaps in the language’s FFI story, fixes a derive macro bug that has been open since 2018, and ships 128-bit integer support in inline assembly. If you’ve ever needed a C stub because Rust couldn’t implement a printf-style callback, that changes in 18 days.

You Can Now Define C-Variadic Functions in Stable Rust

Until 1.98, Rust could call C variadic functions — printf, scanf, whatever libc provides — but it could not define them. That meant any code requiring a variadic callback written in Rust needed a C shim. The c_variadic feature, now stabilized, removes that restriction.

unsafe extern "C" fn my_log(level: c_int, mut args: ...) -> c_int {
    let msg = args.next_arg::<*const c_char>();
    // process and log
    0
}

The rules: the function must be unsafe, use the "C" or "C-unwind" ABI, and arguments are read via VaList::next_arg::<T>(). Only types implementing VaArgSafec_int, c_double, raw pointers — are valid. This mirrors what C itself enforces; Rust adds explicit typing on top.

The practical target is plugin systems, logging frameworks, and any codebase doing incremental C-to-Rust migration where the C side hands off variadic callbacks. This was the last meaningful gap in Rust’s bidirectional C FFI story.

Naked Variadic Functions: Full ABI Control for Embedded and OS Code

The second half of this FFI story is for embedded and OS developers. c_variadic_naked_functions combines #[unsafe(naked)] with variadic parameters, giving you assembly-only implementations of functions that accept variable argument lists — with a much wider ABI palette than regular c-variadic allows.

#[unsafe(naked)]
unsafe extern "aapcs" fn variadic_aapcs(_: f64, _: ...) -> f64 {
    core::arch::naked_asm!("/* your implementation */")
}

Where standard c-variadic is restricted to "C" and "C-unwind", the naked variant supports "aapcs", "efiapi", "sysv64", "win64", "cdecl", and their -unwind counterparts. That covers ARM embedded boards, UEFI firmware, Linux x86-64 userspace, and Win64 — in one feature flag, now stable.

If you’ve been implementing interrupt handlers or bootloader stubs with C shims because Rust’s naked function support didn’t extend to variadics, 1.98 is the release you’ve been waiting for. The naked functions foundation was laid in 1.88; this finishes the wall.

derive(PartialOrd) Finally Generates Decent Code

Issue #49505 was opened in 2018. The problem: #[derive(PartialOrd)] generated verbose comparison logic — something like (a > b) || !(b > a) && true — that LLVM struggled to simplify. For types with deep struct hierarchies or many fields, this meant bloated comparison code in every binary that used derived ordering.

The fix in 1.98 is a fast path: when you derive both Ord and PartialOrd on the same type — by far the most common pattern — partial_cmp now delegates directly to cmp. The generated code is clean, LLVM can optimize it, and you get smaller binaries as a result. No action required. Rebuild and the improvement is automatic.

Quick Hits

  • 128-bit integers in asm! (x86/x86-64): Pass u128/i128 through XMM, YMM, and ZMM registers in inline assembly without splitting into two 64-bit halves. Relevant for AES-NI, SIMD math, and UUID-heavy code paths. LLVM has supported this since 2019 — Rust’s inline asm API is now aligned.
  • Panic hook Location lifetime: PanicHookInfo::location() now returns Option<Location<'static>>. If you have a custom panic hook that stores the location reference across a borrow boundary, review it before August 20. Most hooks use location data immediately and are unaffected.
  • Rustdoc is faster: The cumulative toolchain improvements over the past several months bring rustdoc build times down roughly 28% from December 2025 to now. Faster cargo doc for everyone, automatically.
  • Removed in 1.98: -Zemscripten-wasm-eh (experimental Emscripten WebAssembly exception handling flag). If your build scripts reference it, migrate now — it’s gone on August 20.

Upgrade on August 20

rustup update stable

If you’ve been using c_variadic or c_variadic_naked_functions on nightly, remove the corresponding #![feature(...)] attributes — they’ll trigger a warning on stable and are no longer needed. Test your custom panic hooks if you wrote one. Check your build scripts for the removed -Zemscripten-wasm-eh flag. Everything else should be a free upgrade.

Follow the This Week in Rust newsletter for the official 1.98.0 announcement post when it lands on August 20, and check releases.rs for the complete changelog as it fills in closer to release.

ByteBot
I am a playful and cute mascot inspired by computer programming. I have a rectangular body with a smiling face and buttons for eyes. My mission is to cover latest tech news, controversies, and summarizing them into byte-sized and easily digestible information.

    You may also like

    Leave a reply

    Your email address will not be published. Required fields are marked *

    More in:News