When to Use const fn in Rust: Decision Guide and Example
Learn when to declare a Rust function as const, see the constraints, compare const fn vs regular fn, and view a compile‑time factorial example.
13 Feb 2026, 03:30 UTC

Decision and Constraints
You need a value that the compiler can compute while building the program—for example, the length of an array, a const generic parameter, or the initializer of a static. Declaring the function as const fn makes it usable in those contexts.
Constraints: a const fn may only call other const fns, must use only const‑safe operations (no heap allocation, no panics, no mutable statics), and cannot contain non‑const loops or I/O.
Comparison Table
| Aspect | const fn | regular fn |
|---|---|---|
| Compile‑time evaluation | Yes, when called in a const context | No |
| Allowed operations | Subset of Rust (no heap, no panic) | Full language |
| Runtime overhead | None when used in const context | Normal call overhead |
| Typical use cases | Array sizes, const generics, static values | General purpose logic |
Trade‑offs
Using const fn gives zero‑cost compile‑time computation and enables APIs that require const values, but it restricts expressiveness: you cannot allocate, panic, or use loops whose bounds are not known at compile time. A regular fn retains full language power but cannot be used where the compiler needs a const.
Example Implementation
The following code defines a factorial function that can be evaluated at compile time, uses it to set an array length, and prints the length at runtime.
const fn fact(n: u64) -> u64 {
if n <= 1 {
1
} else {
n * fact(n - 1)
}
}
const FACT_5: u64 = fact(5); // 120
fn main() {
let arr: [u8; FACT_5 as usize] = [0; FACT_5 as usize];
println!("array length = {}", arr.len());
}
Verification Steps
- Compile the example with a recent stable Rust compiler (
rustc 1.60+):rustc example.rs && ./example. The program should printarray length = 120. - To confirm the function works in both const and runtime contexts, change
mainto pass the result to a regular function:fn use_value(v: u64) -> u64 { v + 1 } fn main() { let x = use_value(FACT_5); println!("value + 1 = {}", x); }Re‑compile and run; the program should printvalue + 1 = 121. - Attempt to call a non‑const function from within
fact, for example by allocating a Vec:const fn bad(n: u64) -> u64 { let _ = Vec::with_capacity(n as usize); // error: non‑const call 0 }Compiling this will produce an error about a non‑const call, confirming the constraint.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.