Rust 1.94.1: What Changed and What to Do

intermediate 9 min read updated 2 Aug 2026
On this page 9

Rust 1.94.1: Upgrade Verdict

Rust 1.94.1 resolves a memory corruption issue within std::collections::VecDeque. This bug could manifest when VecDeque instances were resized concurrently across multiple threads. Under specific timing conditions, the internal buffer could become misaligned, leading to heap corruption, application crashes, or incorrect data reads. This fix is particularly important for services that use VecDeque in high-concurrency scenarios, where data integrity is paramount.

The release also includes a fix for a performance regression affecting cargo check on Windows. Users who upgraded to Rust 1.94.0 reported significantly increased cargo check times, especially when project files resided on network shares or certain remote file systems. This patch addresses the underlying I/O inefficiencies, restoring cargo check performance to its expected levels on Windows platforms.

Furthermore, Rust 1.94.1 corrects an issue with cargo doc generation. Projects with complex build.rs scripts or custom target configurations sometimes failed to produce complete documentation, or the process would error out. This update ensures cargo doc functions reliably across a broader range of project setups, providing correct and full documentation output.

Verdict: Upgrade Now

The VecDeque memory corruption fix is a critical stability improvement, addressing a potential security vulnerability. This makes upgrading to 1.94.1 essential for any project relying on concurrent VecDeque usage. The cargo check performance fix for Windows users is also a significant quality-of-life improvement.

To update your toolchain, run:

rustup update stable

If you operate in an environment with multiple installed toolchains, you might specify the target:

rustup update stable-x86_64-pc-windows-msvc

Confirm the update was successful by checking the version:

rustc --version

You should see output similar to this:

rustc 1.94.1 (a1b2c3d4e 2024-07-15)

This update ensures your projects benefit from enhanced stability and corrected tooling performance.

How WASM Threads Fix std::thread::spawn

Before Rust 1.94.1, std::thread::spawn was unusable in WebAssembly (WASM) targets. The standard library’s threading primitives rely on operating system-level threading, which the JavaScript runtime environment fundamentally lacks. This meant any attempt to create a new thread via std::thread::spawn would result in a runtime panic or a compilation error, effectively limiting Rust WASM applications to a single execution thread. Developers needing concurrent operations resorted to manual Web Worker implementations, which introduced significant boilerplate for message passing, state synchronization, and worker lifecycle management.

Rust 1.94.1 addresses this by mapping std::thread::spawn to the WebAssembly Threads API. This API, built upon SharedArrayBuffer, provides true shared-memory concurrency within the browser environment. With this update, Rust’s std::thread now correctly translates to WASM thread primitives, allowing multi-threaded Rust code to execute directly in the browser without complex JavaScript interop layers. This simplifies the architecture for concurrent WASM applications.

To use WASM threads, your web server must enable Cross-Origin Isolation by setting two HTTP response headers: Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp. These headers are necessary to activate SharedArrayBuffer in the browser. Without them, std::thread::spawn will still fail, as the underlying shared memory capability remains disabled. This is a deployment consideration, not a Rust language feature limitation.

Consider this minimal example. Prior to 1.94.1, compiling this for wasm32-unknown-unknown and running it in a browser would fail.

use std::thread;

fn main() {
    let data = vec![1, 2, 3];
    let handle = thread::spawn(move || {
        // Perform some computation in a separate thread
        data.iter().sum::<i32>()
    });

    let sum = handle.join().expect("thread panicked");
    println!("Sum from thread: {}", sum);
}

With Rust 1.94.1 and the correct server configuration, this code now executes, demonstrating a fundamental shift in WASM concurrency. This change is critical for compute-intensive WASM applications that can benefit from parallel execution.

This fix affects all Rust projects targeting WebAssembly that require multi-threading or are currently using manual Web Worker setups to simulate concurrency. It provides a direct and idiomatic way to write concurrent Rust code for the web.

Verdict: Upgrade now. This release is an important step for any WASM project aiming for shared-memory concurrency, provided you can configure your server for Cross-Origin Isolation.

Windows OpenOptionsExt Internals: Unstable API Removal

Rust 1.94.1 removes several unstable methods from std::os::windows::fs::OpenOptionsExt. This change affects code that previously used access_mode, share_mode, security_qos_flags, security_descriptor, or attributes to control Windows file opening behavior. These methods were never stabilized and exposed raw WinAPI concepts directly. Their presence in OpenOptionsExt made it challenging to evolve the standard library’s filesystem API while maintaining consistency and safety across platforms.

Prior to this release, using these methods would generate a compiler warning about unstable API usage. As of 1.94.1, such code will no longer compile. For example, attempts to set a specific share mode directly will now fail:

use std::fs::OpenOptions;
use std::os::windows::fs::OpenOptionsExt;
use windows_sys::Win32::Storage::FileSystem::{FILE_SHARE_READ, FILE_SHARE_WRITE};

fn main() {
    let mut options = OpenOptions::new();
    // This line will cause a compilation error in Rust 1.94.1
    // options.share_mode(FILE_SHARE_READ | FILE_SHARE_WRITE);
    // ...
}

Developers relying on these specific, low-level Windows file options must update their code. For most common file access patterns, std::fs::OpenOptions provides stable, cross-platform methods like read, write, create, and truncate. These should be preferred where possible, as they offer portability and a simpler interface.

For advanced scenarios requiring precise control over share modes, security attributes, or other Windows-specific flags, consider using platform-specific crates or direct FFI calls. The windows-rs crate offers idiomatic Rust bindings to the Windows API, allowing direct calls to functions like CreateFileW with all its parameters. Using such crates or FFI requires unsafe blocks and knowledge of the underlying Windows API semantics, including proper handle management and error checking. This approach provides granular control but introduces platform dependency and requires careful handling of raw pointers and error codes.

The removal simplifies the standard library’s Windows filesystem API, focusing on what can be safely and stably abstracted. It ensures the standard library does not commit to exposing raw operating system details that are difficult to maintain or port across future Rust versions or different operating systems.

Cargo tar CVE & Clippy ICE: Stability Updates

Rust 1.94.1 addresses a security vulnerability in Cargo and fixes a Clippy internal compiler error. The Cargo issue is crucial for security.

A tar file vulnerability in Cargo could allow arbitrary file writes outside the build directory during cargo install or cargo build operations. When Cargo extracts archives from untrusted sources, such as during cargo install from a malicious git repository or when a path dependency points to a crafted .tar file, path traversal could occur.

This vulnerability affects users who install crates from untrusted sources via cargo install, or whose projects use path dependencies that might originate from untrusted repositories. The fix in 1.94.1 restricts Cargo’s tar extraction to the intended target directory, preventing files from being written to arbitrary locations.

All users of cargo install or those working with path dependencies from external sources should upgrade immediately to mitigate this risk.

Clippy also received a stability update. An Internal Compiler Error (ICE) could occur when Clippy analyzed specific code patterns, leading to a crash. This issue prevented linting from completing for affected projects, potentially disrupting CI pipelines or local development flows.

The fix resolves this ICE, allowing Clippy to process the problematic code patterns without error. If your tooling frequently encounters Clippy crashes, this update will improve stability.

Verdict: Upgrade now. The Cargo tar vulnerability is a significant security concern requiring immediate action. The Clippy fix improves tooling stability for affected users.

Migration Considerations: Unstable Features and Security

Rust 1.94.1 addresses a security vulnerability, modifies an unstable feature, and corrects a BufReader behavior.

A security vulnerability in std::fs::read_link on Windows has been patched. Previously, specially crafted symbolic link target paths could lead to path traversal. The function now correctly normalizes paths returned by the operating system, preventing components like .. from escaping the intended directory if they were present in the raw target path from the OS.

This affects applications running on Windows that use std::fs::read_link to process symbolic link targets, particularly if these targets originate from untrusted sources. No code changes are required. The fix is internal to the standard library.

Verdict: Upgrade now. This is a critical security fix for Windows users.

Unstable Feature: const_pin Behavior Change

The #[feature(const_pin)] implementation has been adjusted. Specifically, Pin::new_unchecked in const contexts now requires the inner value to be Sized and Sync when used within static items. This change aligns the const behavior with the runtime guarantees of Pin, ensuring type safety in compile-time pinned references.

Users relying on const_pin to create static pinned references to unsized or non-Sync types will encounter new compilation errors. For example, attempting to Pin::new_unchecked an unsized trait object directly in a static context will now fail.

To migrate, review code using Pin::new_unchecked within static items under const_pin. Ensure the types being pinned satisfy Sized and Sync constraints. If you require pinning unsized types, consider using Box::pin at runtime or re-evaluate the necessity of const pinning for that specific case.

#![feature(const_pin)]

// This example code would now fail to compile with Rust 1.94.1
// if `MyUnsizedOrUnsyncType` were not Sized and Sync.
/*
struct MyUnsizedOrUnsyncType; // e.g., `dyn Trait` or a custom unsized type
static MY_STATIC_PIN: &'_ core::pin::Pin<&'static MyUnsizedOrUnsyncType> = {
    &core::pin::Pin::new_unchecked(&MyUnsizedOrUnsyncType) // Now requires Sized + Sync
};
*/

// To resolve, ensure the type is Sized and Sync for static const pinning:
struct MySizedSyncType;
static MY_STATIC_PIN_OK: &'_ core::pin::Pin<&'static MySizedSyncType> = {
    &core::pin::Pin::new_unchecked(&MySizedSyncType)
};

Verdict: Upgrade now if you use const_pin and adapt affected code. Otherwise, wait or skip.

Behavioral Fix: std::io::BufReader fill buffer logic

A bug in std::io::BufReader’s internal buffer filling logic has been corrected. Previously, BufReader::fill_buf could sometimes return an empty slice even when more data was available from the underlying reader, necessitating an extra read operation. The fix ensures fill_buf actively attempts to read data into its buffer if it is empty and the end of the underlying stream has not been reached.

This affects users of std::io::BufReader who might have observed non-optimal performance or unexpected empty slices in specific streaming scenarios. No code changes are required. The fix improves BufReader’s reliability and efficiency.

Verdict: Upgrade now. This is a beneficial bug fix.

Upgrade Now or Wait: Decision Matrix

Rust 1.94.1 fixes a critical data corruption bug in std::io::BufReader when used with tokio’s AsyncRead traits. This regression, introduced in 1.94.0, can lead to incorrect data being read from network streams under high concurrency. Applications using tokio and BufReader with network I/O are directly affected.

If your application uses tokio and BufReader for network operations, an immediate upgrade to 1.94.1 is necessary. This addresses the data corruption issue directly.

rustup update stable

The release also includes compiler optimizations for match statements over large enums. This can reduce binary size and improve branch prediction performance on x86-64 targets, particularly for applications with complex state machines or parsers. Benchmarks show up to a 3% reduction in CPU cycles for specific workloads.

For projects where binary size or CPU performance is a critical metric, consider upgrading to 1.94.1 to benefit from these optimizations. Profiling your application before and after the upgrade can confirm the impact. If performance is not a bottleneck, you can wait for your next scheduled update.

A minor enhancement in cargo doc adds the --generate-html-only flag. This option prevents the generation of the search index, which can speed up documentation builds in CI environments where search functionality is not required.

This cargo doc change is low impact for most development workflows. If your CI pipeline spends significant time generating documentation and you do not use the search index, integrate this flag during a convenient maintenance window. Otherwise, there is no immediate need to upgrade for this feature alone.

Verdict:

  • Upgrade now: If your application uses tokio and BufReader with network I/O. This is a critical bugfix.
  • Upgrade when convenient: If your application uses complex match statements on x86-64, or if you need the cargo doc --generate-html-only flag.
  • Skip: If none of the above apply, you can defer this patch to your regular update cycle.