pub trait Recurse {
// Required method
fn recurse<T>(&'static self, _: impl FnOnce(&Tracker) -> T) -> T;
}
Expand description
The extension trait for a thread-local tracker to run a recursive function.
Required Methods§
sourcefn recurse<T>(&'static self, _: impl FnOnce(&Tracker) -> T) -> T
fn recurse<T>(&'static self, _: impl FnOnce(&Tracker) -> T) -> T
Run the given recursive function. Grow the stack if necessary.
§Fearless Recursion
This enables fearless recursion in most cases as long as a single frame
does not exceed the RED_ZONE
size. That is, the caller can recurse
as much as it wants without worrying about stack overflow.
§Tracker
The caller can retrieve the Tracker
of the current recursion from
the closure argument. This can be useful for checking the depth of the
recursion, logging or throwing an error gracefully if it’s too deep.
Note that different trackers defined in different functions are independent of each other. If there’s a cross-function recursion, the tracker retrieved from the closure argument only represents the current function’s state.
§Example
Define the tracker with tracker!
and call this method on it to run
a recursive function.
#[inline(never)]
fn sum(x: u64) -> u64 {
tracker!().recurse(|t| {
if t.depth() % 100000 == 0 {
eprintln!("too deep!");
}
if x == 0 {
return 0;
}
x + sum(x - 1)
})
}