rust-clippy
rust-clippy copied to clipboard
Suggest ! return type for functions that never return a value
What it does
Rust's !
type, also known as the never
type, signifies that a function never returns normally. Clippy currently doesn't have a lint to suggest using !
when a function never returns a value or will result into diverging computation(eg., an infinite loop or panic), which could lead to potential type safety issues and misleading code patterns.
Advantage
- Improved type safety by preventing accidental assignment of panic-only functions to variables expecting a value.
- Clearer code intent, making it more obvious when functions don't return normally.
- Potential for better error handling and code analysis.
Drawbacks
-
never
type is still in nightly, and still will take time before it's stabilized, so better to wait in that case. (https://doc.rust-lang.org/nightly/std/primitive.never.html) - It could be challenging to write a foolproof lint that accurately distinguishes functions that always panic from those that may return under some conditions.
Example
fn will_error_out() {
panic!("It returns nothing, but it's not known to compiler")
}
This function always panics, but its return type is implicitly () (unit), suggesting it might return a value. Adding ! as the return type would clarify its behavior:
fn will_error_out() -> ! {
panic!("It returns nothing, but it's now explicit")
}
Specifying a never
return type will make it easier for its usage in where other functions are dependent on this function.
let some_value: bool = will_error_out(); // will not error out for second case
This should ignore both unimplemented!
and todo!
when checking.
Yes, I agree. The linter should only warn when a function either:
- Contains an unconditional panic!()
- Unconditionally exits the program
- Unconditionally calls a method that never returns
- Contains an infinite loop
Checking for infinite loops comprehensively might be difficult, but even basic checks would be helpful.
FYI, function contains infinite loop is already linted 😄 infinite_loop
FYI, function contains infinite loop is already linted 😄 infinite_loop
Thanks for pointing it out! I think that lint can be used as reference for implementing this one! Also, I think it will be more sane to merge this one in infinite loop one, as both are targeting never return only?(need opinions) 😄