[][src]Attribute Macro tailcall::tailcall

#[tailcall]

Transforms a function definition so that all recursive calls within the body are guaranteed to use a single stack frame (via tail recursion).

Example

use tailcall::tailcall;

fn factorial(input: u64) -> u64 {
    #[tailcall]
    fn factorial_inner(accumulator: u64, input: u64) -> u64 {
        if input > 0 {
            factorial_inner(accumulator * input, input - 1)
        } else {
            accumulator
        }
    }

    factorial_inner(1, input)
}

Requirements

This example deliberately fails to compile
use tailcall::tailcall;
   
#[tailcall]
fn factorial(input: u64) -> u64 {
    if input > 0 {
        input * factorial(input - 1)
//      ^^^^^^^ This is not allowed.
    } else {
        1
    }
}
  • Methods (functions which bind self in the arguments list) are not supported:
This example deliberately fails to compile
trait Factorialable {
    fn factorial(self) -> Self {
        self.calc_factorial(1)
    }

    fn calc_factorial(self, accumulator: u64) -> u64;
}

impl Factorialable for u64 {
    #[tailcall]
    fn calc_factorial(self, accumulator: u64) -> u64 {
//                    ^^^^ This is not allowed.
        if self > 0 {
            (self - 1).calc_factorial(self * accumulator)
        } else {
            accumulator
        }
    }
}
  • No identifier with the name ___tailcall___ may appear anywhere within the body:
This example deliberately fails to compile
use tailcall::tailcall;

fn factorial(input: u64) -> u64 {
    #[tailcall]
    fn factorial_inner(accumulator: u64, input: u64) -> u64 {
        mod ___tailcall___ {
//          ^^^^^^^^^^^^^^ This is not allowed.
            pub fn one() -> u64 {
                1
            }
        }

        if input > 0 {
            factorial_inner(accumulator * input, input - ___tailcall___::one())
        } else {
            accumulator
        }
    }

    factorial_inner(1, input)
}