Rust has spent a decade earning its reputation as the language that makes systems programming safe without sacrificing performance. In 2026, that reputation is translating into concrete infrastructure changes. Rust 1.94, released in early 2026, makes LLD the default linker on Linux targets, the Linux kernel's Rust subsystem is accepting driver submissions beyond proof-of-concept, and the Edition 2024 migration is reaching critical mass across the ecosystem.

This post covers what changed, why it matters, and where Rust stands relative to the broader systems programming landscape.

Rust systems programming in 2026 Systems programming is undergoing a generational shift as memory-safe languages gain kernel-level adoption

LLD as the Default Linker

The Problem with the System Linker

For most of its history, Rust on Linux delegated linking to whatever the system provided — typically GNU ld (BFD) or GNU Gold. This worked, but it introduced several pain points:

  • Build times: GNU ld is single-threaded for most of its work. On large projects with hundreds of crates, linking could take 30–60 seconds, sometimes longer than compilation itself.
  • Inconsistency: Different distributions ship different linker versions with different defaults. A binary that links fine on Ubuntu might fail on Alpine or older RHEL.
  • LTO friction: Link-time optimization with the system linker required careful coordination between the LLVM bitcode Rust emits and the linker's expectations.

What Rust 1.94 Changes

Starting with Rust 1.94, rustc defaults to using LLD (the LLVM linker) for x86_64-unknown-linux-gnu and aarch64-unknown-linux-gnu targets. LLD ships as part of the Rust toolchain via rustup, so no system package installation is required.

The practical effects are significant:

# Before Rust 1.94 — system linker
$ time cargo build --release
# Linking phase: ~42s on a 500-crate workspace

# After Rust 1.94 — LLD default
$ time cargo build --release
# Linking phase: ~8s on the same workspace

LLD achieves this speedup through aggressive parallelism. It parallelizes symbol resolution, section merging, and relocation processing — operations that GNU ld handles sequentially.

Configuration and Overrides

The default can be overridden in .cargo/config.toml:

[target.x86_64-unknown-linux-gnu]
linker = "clang"
rustflags = ["-C", "link-arg=-fuse-ld=/usr/bin/ld"]

For projects that depend on GNU linker scripts or specific ld behavior, the override is straightforward. However, the Rust team has been tracking compatibility issues for over two years, and the vast majority of crates link correctly with LLD without changes.

LLD has been the default linker for Rust's Windows MSVC targets since 2019 and for `wasm32` targets since their introduction. The Linux default change brings parity across major platforms.

Linker Comparison

Feature GNU ld (BFD) GNU Gold LLD
Parallel linking No Partial Yes
LTO integration External plugin External plugin Native LLVM
Incremental linking No No Partial
Linker script support Full Partial Partial
Cross-compilation Requires per-target build Requires per-target build Single binary, all targets
Ships with Rust No No Yes (via rustup)

The trade-off is linker script compatibility. Projects relying on complex custom linker scripts — common in embedded and OS development — may still need GNU ld. For the majority of application and library development, LLD is a strict improvement.

Rust in the Linux Kernel

From Experiment to Infrastructure

Rust support entered the Linux kernel in version 6.1 (December 2022) as experimental infrastructure. By kernel 6.12 and into the 6.13–6.14 cycle, the story has changed substantially:

  • The Rust-for-Linux project provides stable abstractions for kernel APIs including struct file_operations, workqueues, and memory allocation.
  • The Android team has contributed production Rust drivers, including Binder IPC components.
  • The rust-next branch in the kernel tree regularly merges patches from multiple corporate contributors.

What Kernel Rust Looks Like

A minimal kernel module in Rust demonstrates the abstraction layer:

use kernel::prelude::*;

module! {
    type: MyModule,
    name: "my_module",
    author: "Developer",
    description: "A minimal Rust kernel module",
    license: "GPL",
}

struct MyModule;

impl kernel::Module for MyModule {
    fn init(_module: &'static ThisModule) -> Result<Self> {
        pr_info!("Rust module loaded\n");
        Ok(MyModule)
    }
}

impl Drop for MyModule {
    fn drop(&mut self) {
        pr_info!("Rust module unloaded\n");
    }
}

This looks deceptively simple, but the kernel::prelude and module! macro handle substantial complexity: kernel memory allocation (which can fail, unlike userspace malloc which typically overcommits), proper module metadata for modinfo, and safe wrappers around the C kernel API.

The Safety Argument

The motivation for Rust in the kernel is empirical. Studies from Microsoft, Google, and the Chromium project consistently show that approximately 70% of serious security vulnerabilities in large C/C++ codebases are memory safety issues — use-after-free, buffer overflows, uninitialized memory reads.

The kernel is not immune. CVE data for the Linux kernel shows a steady stream of memory safety bugs in drivers, file systems, and networking code. Rust's ownership model eliminates entire categories of these bugs at compile time.

Rust in the kernel does not eliminate all bugs. Logic errors, deadlocks, and incorrect algorithm implementations remain possible. Rust addresses memory safety and data race prevention specifically — but those categories account for the majority of exploitable kernel vulnerabilities.

Kernel Rust Adoption Timeline

Year Milestone
2020 Rust-for-Linux project begins, RFC discussions on LKML
2022 Rust infrastructure merged into Linux 6.1
2023 First real driver abstractions, Android Binder work begins
2024 rust-next branch stabilizes, file system abstractions proposed
2025 Multiple production drivers merged, NVMe driver prototype demonstrated
2026 Kernel build system natively supports Rust modules, expanded driver coverage

Edition 2024 Migration

What Editions Are

Rust editions (2015, 2018, 2021, 2024) allow the language to evolve without breaking existing code. Each edition can introduce new keywords, change syntax semantics, and update defaults. Crates on different editions interoperate freely — a 2024-edition crate can depend on a 2015-edition crate without issues.

Key Edition 2024 Changes

Edition 2024, stabilized with Rust 1.85, introduced several changes that affect daily coding:

Lifetime capture rules in impl Trait: In previous editions, -> impl Trait return types did not capture all input lifetimes by default. Edition 2024 changes this to capture all in-scope lifetimes, reducing a common source of confusing lifetime errors.

// Edition 2021 — does NOT capture 'a, may cause errors
fn process(data: &str) -> impl Iterator<Item = &str> {
    data.split(',')
}

// Edition 2024 — captures the input lifetime automatically
// Same code, but the compiler understands the lifetime relationship
fn process(data: &str) -> impl Iterator<Item = &str> {
    data.split(',')
}

unsafe_op_in_unsafe_fn lint enabled by default: Previously, the body of an unsafe fn was implicitly an unsafe block. Edition 2024 requires explicit unsafe {} blocks inside unsafe functions, improving auditability.

// Edition 2024 — must be explicit about unsafe operations
unsafe fn dangerous_operation(ptr: *const u8) -> u8 {
    // This now requires an explicit unsafe block
    unsafe { *ptr }
}

gen keyword reserved: The gen keyword is reserved for future generator/coroutine syntax, reflecting ongoing work on ergonomic async and iterator patterns.

Migration Tooling

The cargo fix --edition command handles most migrations automatically:

# Update Cargo.toml to edition 2024
cargo fix --edition

# Verify the migration
cargo check
cargo test
Before running `cargo fix --edition`, ensure your project compiles without warnings on the current edition. The migration tool works best on clean code. Also run `cargo clippy` first — some Clippy lints overlap with edition changes and resolving them beforehand simplifies the migration.

As of early 2026, the top 1000 crates on crates.io are largely compatible with Edition 2024, with the ecosystem migration proceeding faster than the 2018 and 2021 transitions.

Async Rust Improvements

The State of Async

Async Rust has been functional since Rust 1.39 (2019), but it has been one of the language's rougher edges. The 2024–2026 period has brought meaningful improvements:

async fn in traits — Stabilized in Rust 1.75 and refined through subsequent releases, this feature eliminated the need for the async-trait crate's proc-macro approach. Trait methods can now be natively async:

trait DataStore {
    async fn fetch(&self, key: &str) -> Result<Vec<u8>, Error>;
    async fn store(&self, key: &str, value: &[u8]) -> Result<(), Error>;
}

Async closures — Stabilized in Rust 1.85 as part of Edition 2024, async || { ... } closures resolve a long-standing ergonomic gap. Previously, combining closures with async code required manual Future construction or async move blocks with awkward signatures.

Async iterators (streams): Work continues on AsyncIterator and gen blocks. While not fully stabilized as of Rust 1.94, nightly builds include experimental support for async gen blocks that yield values asynchronously, unifying the iterator and stream patterns.

Runtime Ecosystem

The async runtime landscape has stabilized around a few major options:

  • Tokio remains the dominant general-purpose runtime, with mature support for I/O, timers, and task scheduling.
  • smol offers a lightweight alternative for smaller applications.
  • Embassy targets embedded systems with a no-std async runtime, gaining significant traction in the microcontroller space.

Rust async ecosystem and tooling in 2026 The async Rust ecosystem has matured significantly, with stable traits and growing runtime options

Adoption Numbers

Rust's adoption continues to grow across multiple dimensions:

  • Stack Overflow Developer Survey: Rust has been the "most admired" language for several years running. The 2025 survey showed approximately 10% of professional developers using Rust regularly, up from around 7% in 2023.
  • crates.io: The registry passed 160,000 crates in 2025, with download counts growing year-over-year.
  • Corporate adoption: Amazon (Firecracker, Bottlerocket, S3), Google (Android, ChromeOS, Fuchsia), Microsoft (Windows kernel components, Azure), Meta (source control tooling), and Cloudflare (Pingora proxy) all have production Rust deployments.
  • Government endorsement: The US Cybersecurity and Infrastructure Security Agency (CISA) and the White House Office of the National Cyber Director have recommended memory-safe languages for critical infrastructure, explicitly naming Rust as a preferred option.

Rust Foundation Updates

The Rust Foundation, established in 2021, has expanded its role beyond financial stewardship:

  • Security initiative: The Foundation funds security audits of critical crates and maintains the cargo-audit database of known vulnerabilities.
  • Infrastructure funding: crates.io infrastructure, CI resources, and the Rust playground are Foundation-funded.
  • Trademark policy: After community feedback in 2023, the Foundation revised its trademark policy to be more permissive for community use while protecting against misleading commercial use.
  • Grants program: The Fellowship and Community Grants programs have funded contributor time on compiler improvements, documentation, and ecosystem tooling.

Rust vs. C++ Modernization

Parallel Paths

Both Rust and C++ are addressing memory safety, but through fundamentally different mechanisms:

C++ approach: The C++ community is pursuing safety through profiles (proposed for C++26 and beyond), static analysis tools, sanitizers, and coding guidelines (C++ Core Guidelines). The Safe C++ proposal by Sean Baxter introduces a Rust-like borrow checker as an opt-in extension. Carbon, Google's experimental C++ successor, takes a different approach by providing interoperability with C++ while redesigning the language.

Rust approach: Memory safety is enforced by the compiler by default. Unsafe code is explicit, contained, and auditable. The language does not have a "legacy unsafe mode" — safety is the baseline.

The Interoperability Reality

In practice, Rust and C++ coexist. The cxx crate provides zero-overhead FFI between Rust and C++, and projects like the Android platform, Chromium, and the Linux kernel use both languages side by side. The question is not whether Rust replaces C++ — it is whether new systems code defaults to Rust while existing C++ codebases adopt incremental safety improvements.

// Using cxx for C++ interoperability
#[cxx::bridge]
mod ffi {
    unsafe extern "C++" {
        include!("mylib/include/engine.h");

        type Engine;
        fn create_engine() -> UniquePtr<Engine>;
        fn process(self: &Engine, input: &[u8]) -> Vec<u8>;
    }
}
The C++ Interop story is bidirectional. The `cxx` crate generates both Rust and C++ code, and the `autocxx` crate can automatically generate Rust bindings from C++ headers, reducing the manual effort of integrating Rust into existing C++ projects.

What Comes Next

Several developments are on the horizon for Rust in 2026 and beyond:

  • Polonius: The next-generation borrow checker, Polonius, continues to advance toward stabilization. It handles several patterns that the current borrow checker rejects unnecessarily, particularly around conditional borrowing.
  • gen blocks and async generators: The reserved gen keyword in Edition 2024 points toward first-class generator support, which would simplify iterator and stream implementations.
  • Stable ABI discussions: While no stable ABI has been committed to, ongoing discussions explore options for stable dynamic linking, which would enable Rust-based plugin systems without recompilation.
  • Expanded kernel support: The Rust-for-Linux project is working toward broader driver class support, including networking and file system drivers, with the goal of making Rust a first-class kernel development language alongside C.
  • Formal verification tooling: Projects like Kani (from Amazon) and Creusot provide model checking and formal verification for Rust code, an area of active research that benefits from Rust's strong type system.

Conclusion

Rust 1.94's LLD default is a small change with outsized practical impact — faster builds across the ecosystem with no configuration required. But it is also representative of Rust's broader trajectory: steady, practical improvements that compound over time. The kernel work, the async maturation, the edition migration, and the growing adoption numbers all point in the same direction.

Rust is not replacing C or C++ overnight. Large codebases do not get rewritten on a whim. What is happening is more gradual and arguably more durable: Rust is becoming the default choice for new systems code, and the tooling and ecosystem are maturing to support that position. The LLD change, the kernel modules, and the edition migration are not individual events — they are milestones on a trajectory that has been building for a decade and is now reaching critical mass.

Comments