Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The never type, denoted by !, is a primitive type in Rust representing a computation that never resolves to a value. In type theory, it is known as the bottom type or empty type. Because the never type has no inhabitants (zero possible values), it is impossible to instantiate at runtime. When a function returns !, it signals to the compiler that the function will never return control to the caller. This occurs through infinite loops, process termination, or panics.
// The return type ! indicates this function never yields a value.
fn diverge() -> ! {
    loop {
        // non-terminating execution
    }
}

Type Coercion and the Bottom Type

The most significant mechanical property of ! is that it can be implicitly coerced into any other type in the Rust type system. Because a computation evaluating to ! never completes, any subsequent code is mathematically unreachable. The compiler leverages this unreachability to safely bypass type-checking constraints for the diverging branch.
let an_option: Option<u32> = None;

// The match expression requires all arms to return the same type (u32).
let value: u32 = match an_option {
    Some(num) => num,      // Evaluates to u32
    None => diverge(),     // Evaluates to !, implicitly coerced to u32
};
In the example above, the compiler allows the None arm to compile because diverge() produces !. Since ! guarantees the assignment to value will never occur, coercing ! to u32 is memory-safe and logically sound.

Memory Layout

The never type has a size of 0 bytes. However, it is fundamentally different from the unit type ().
  • The unit type () has exactly one inhabitant (the value ()). It takes up 0 bytes, but it successfully returns and exists at runtime.
  • The never type ! has zero inhabitants. It takes up 0 bytes because it cannot exist in memory under any circumstances.

Interaction with Generics and Infallible

When a bottom type is substituted into generic types, it restricts the possible states of that type. This is particularly relevant for enums like Result<T, E>. Using the never type ! directly as a generic type parameter (e.g., Result<u32, !>) is currently experimental and requires the nightly #![feature(never_type)] attribute. For stable Rust, the standard library provides std::convert::Infallible, an empty enum that serves as the idiomatic, stable substitute for representing an impossible variant.
use std::convert::Infallible;

// A Result where the Error variant is Infallible.
// This type can only ever exist as Ok(u32).
let safe_computation: Result<u32, Infallible> = Ok(42);
Because Infallible cannot be instantiated, the compiler knows that Result<T, Infallible> can never be Err. However, because the exhaustive_patterns feature is not fully stabilized in Rust, pattern matching on such types historically still requires explicitly handling the impossible variant to satisfy the compiler. This is done using an empty match block:
use std::convert::Infallible;

let result: Result<u32, Infallible> = Ok(42);

let unwrapped: u32 = match result {
    Ok(val) => val,
    Err(e) => match e {}, // Explicitly matching the impossible empty enum
};

Trait Implementations

From a theoretical standpoint, any proposition about the elements of an empty set is vacuously true. Reflecting this, the Rust compiler automatically implements many standard library traits for !. For example, ! implements Send, Sync, Copy, Clone, Eq, PartialEq, Ord, and PartialOrd. Because there is no value of type ! to pass to the methods defined by these traits, the methods can never be called, making the implementations trivially safe.
Master Rust with Deep Grasping Methodology!Learn More