Advanced Generics and Type-Level Programming

const Blocks

An inline const block—written const { ... } (stabilized in Rust 1.79)—is an expression that forces the compiler to evaluate its body at compile time (or monomorphization time when referencing generic parameters), without requiring you to declare a separate named const item outside the function.

Three Core Uses of Inline const { ... } Blocks

1. Initializing Arrays of Non-Copy Types ([const { None }; N])

In Rust, the array repeat expression [expr; N] normally requires expr to implement Copy unless expr is a const item or an inline const { ... } block! With const { None } or const { Vec::new() }, you can initialize large arrays of non-Copy types (Option<String>, Vec<T>, Mutex<T>, MaybeUninit<T>) inline without declaring a helper const:

use std::sync::Mutex;

fn main() {
    // `Option<String>` and `Mutex<Vec<u8>>` do NOT implement `Copy`,
    // yet `[const { ... }; N]` initializes the array at compile time!
    let slots: [Option<String>; 4] = [const { None }; 4];
    let shards: [Mutex<Vec<u8>>; 2] = [const { Mutex::new(Vec::new()) }; 2];

    shards[0].lock().unwrap().push(42);
    println!("slots:    {:?}", slots);
    println!("shard[0]: {:?}", *shards[0].lock().unwrap());
}
slots:    [None, None, None, None]
shard[0]: [42]

2. Compile-Time Assertions Depending on Generic Parameters

Inside a generic function fn process<T, const N: usize>(), an inline const { assert!(...); } block is evaluated at monomorphization time for each concrete (T, N) instantiation, turning violated layout or size constraints into compile-time errors instead of runtime panics:

fn encode_fixed_chunk<T: Copy, const COUNT: usize>(items: &[T; COUNT]) -> usize {
    // Evaluated at compile time when `encode_fixed_chunk` is monomorphized:
    const {
        assert!(COUNT > 0, "COUNT must be non-zero");
        assert!(
            size_of::<T>() <= 8,
            "Element type T must be at most 8 bytes wide"
        );
    }
    items.len() * size_of::<T>()
}

fn main() {
    let data = [10_u32, 20, 30, 40];
    println!("encoded byte length: {}", encode_fixed_chunk(&data));
}
encoded byte length: 16

3. Inline const { ... } Patterns in match Expressions

Stabilized in Rust 1.79 alongside inline const expressions, const { ... } blocks can also be used inside match and if let patterns to match against computed compile-time constants without defining named const items:

const fn page_size(shift: u32) -> usize {
    1 << shift
}

fn classify_allocation(bytes: usize) -> &'static str {
    match bytes {
        0 => "empty",
        1..=const { page_size(12) } => "fits in 4 KiB page",
        const { page_size(12) + 1 }..=const { page_size(21) } => "fits in 2 MiB hugepage",
        _ => "oversized allocation",
    }
}

fn main() {
    println!("512 B:      {}", classify_allocation(512));
    println!("65,536 B:   {}", classify_allocation(65_536));
    println!("16 MiB:     {}", classify_allocation(16 * 1024 * 1024));
}
512 B:      fits in 4 KiB page
65,536 B:   fits in 2 MiB hugepage
16 MiB:     oversized allocation