A proc macro to make recursive functions run on the heap (avoiding stack overflow)

61 points ignusem

Background

The blog post Stack-safety for free? by u/hurryabit describes a way of using generators to make recursive functions recurse on heap-allocated memory instead of the stack, avoiding stack overflow. I found that the technique doesn't actually require generators (which won't be stabilized anytime soon); async/await can be used to accomplish the same thing. So I made a macro for it.

The Crate

The crate is named decurse.

Example Usage:

#[decurse::decurse] // 👈 Slap this on your recursive function and stop worrying about stack overflow!
fn factorial(x: u32) -> u32 {
    if x == 0 {
        1
    } else {
        x * factorial(x - 1)
    }
}

Links

Link to project on GitHub \- examples, limitations, benchmarks, explanations, and more are in the repo.

The crate on crates.io

Safe + Unsafe

The macro #[decurse::decurse] contains no unsafe code. However, it doesn't work on functions with lifetimed arguments.

Another macro is also provided. #[decurse::decurse_unsound] works on functions with lifetimed arguments, but it can cause unsoundness.