What is Clippy against recursion?

⚓ Rust    📅 2026-07-10    👤 surdeus    👁️ 1      

surdeus

I've defined the following little tax calculator:

fn zins_calc(input: f32, zins: f32) -> f32 {
    input - (input * zins)
}

fn tax_calc(input: f32, years: u8) -> f32 {
    let years = years - 1;

    tax_calc(
        zins_calc(
            input,
            if input >= 1.0 * 10.0_f32.powf(6.0) {
                0.12
            } else {
                0.05
            },
        ),
        years,
    )
}

That's what cargo clippy has to say about it:

warning: function cannot return without recursing
  --> src/main.rs:39:1
   |
39 |   fn tax_calc(input: f32, years: u8) -> f32 {
   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
...
42 | /     tax_calc(
43 | |         zins_calc(
44 | |             input,
45 | |             if input >= 1.0 * 10.0_f32.powf(6.0) {
...  |
51 | |         years,
52 | |     )
   | |_____- recursive call site
   |
   = help: a `loop` may express intention better if this is on purpose
   = note: `#[warn(unconditional_recursion)]` on by default

I mean... I know that this is recursion. That was my intention. What I don't know is why the code linter has problems with it. However, the code linter doesn't care about the following little trick:

fn tax_calc(input: f32, years: u8) -> f32 {
    [years - 1].map(|years| {
        tax_calc(
            zins_calc(
                input,
                if input >= 1.0 * 10.0_f32.powf(6.0) {
                    0.12
                } else {
                    0.05
                },
            ),
            years,
        )
    })[0]
}

In terms of functionality, it's the same method with a little encapsulation through the years value. It's still recursion. Why doesn't the linter care about that, yet get angry with the other example?

8 posts - 4 participants

Read full topic

🏷️ Rust_feed