Clippy warnings to remove `return` a bit too much?

I'm curious about the reasoning behind this.

Clippy tells me to remove return statements but if I'm doing early returns in a kludge of code, I would prefer these to be marked explicitly.

Wouldn't it be better to limit enforcing returnless returns to the last statement in a function?

Do you have an example? I can't remember having clippy suggest me to remove a return keyword except in the last statement :slight_smile:

2 Likes

Early returns must use the return keyword, so Clippy cannot ask to remove them. Could you post a relevant code snippet?

I bet you have something like this:

fn foo() -> Option<u32> {
    if early_return_condition {
        return None;
    } else {
        return some_other_calculation();
    }
}

which can be simplified to

fn foo() -> Option<u32> {
    if early_return_condition {
        None
    } else {
        some_other_calculation()
    }
}

The "last expression of the function" does not literally mean the last line only. If the last expression happens to be a structured expression like if or match, it has a value too, so you can omit the returns there as well.

5 Likes

I think it’s fine that you can omit them but should clippy enforce this?

I leave them in because I think it’s clearer if there is code in between a bunch of other code that does a return, to mark it explicitly with the keyword. Especially if you have a complicated nested setup (which of course you shouldn’t have).

You can also transform code like this into an "actual" early return, which will make Clippy happy, and reduce nesting:

fn foo() -> Option<u32> {
    if early_return_condition {
        return None;
    }
    some_other_calculation()
}
4 Likes

Regarding your direct question, I do think clippy should enforce it. Rust is an expression based language, which is different from what a lot of people are used to. Every block evaluates to the value of its last statement. Every function returns the value our evaluates to. It's a powerful pattern, and worth teaching through clippy.

If you have a strong desire to write non idiomatic rust, feel free to disable the lint, but idiomatic rust only uses return when necessary.

5 Likes

Note, it's almost wrong in terms of rust semantics to even think about it as "omitting" a return statement. Explicitly adding the return is as strange in rust as writing

def main():
    import sys
    sys.exit(0)
    return

in Python. It's redundant, and leads the reader to suspect something weird is happening when it's not.

2 Likes

OK. That’s what I wanted to know.

Here's why explicit return statements might be considered unidiomatic: The forgotten art of structured programming (YouTube) (skip to 14m0s for actual arguments)

1 Like

Note that if you look at the core of Go To Statement Considered Harmful, it's about

The unbridled use of the go to statement has an immediate consequence that it becomes terribly hard to find a meaningful set of coordinates in which to describe the process progress.

The one use of goto that doesn't have this problem is using it to exit a block -- and that's exactly what break from loops (including labeled loops), and return do.

That's why clippy doesn't complain about all early returns, as was mentioned above -- only the ones that are unneeded, the same way the compiler complains about unnecessary parentheses.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.