-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Add direct-recursion Lint #15006
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Add direct-recursion Lint #15006
Conversation
@PLeVasseur WIP. I think the implementation is correct. I'll complete the documentation later, hopefully this weekend ^^ |
Nice! Thanks for taking on the implementation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @felix91gr -- thanks for writing this up.
One thing I was unclear on: should this lint also check for recursion that's due to macros or only functions?
Well... since it's a |
d955bfc
to
e06510b
Compare
Sorry for the CI churn. It took me a while to understand why it was failing the |
e06510b
to
30beb95
Compare
rustbot has assigned @samueltardieu. Use |
This comment has been minimized.
This comment has been minimized.
changelog: new lint: [`direct_recursion`]
30beb95
to
1f8f785
Compare
I feel like this should be in the quick CI checks (like the |
Something that I'd like to add in a later PR, is a link to the Safety Critical Coding Guidelines where recursion is addressed. Currently the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice documentation addition, @felix91gr!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't flag all potentially direct recursive calls. For example, it doesn't trigger on this code path:
fn recurse_through_var(x: i32) -> i32 {
let call = if x < 10 {
std::convert::identity
} else {
recurse_through_var
};
call(x - 1)
}
Should I add this caveat to the documentation? Context: That kind of indirect call through a variable is ultimately undecidable (as a consequence of constprop being undecidable). That being said, one can attempt to detect as many of those cases as one can (as most lints that touch on undecidability do). But still, this kind of detection requires MIR machinery that we don't have (in particular, it requires dataflow analysis capable of doing non-lexical constant propagation). I might implement it with the help of some friends in the future, but for now doing this properly in Clippy would require me to implement it in Clippy... which is outside of the scope of this lint. See also: the transmute-null-ptr-to-ref lint. When I implemented it, I stopped at the base cases due to the same lack of dataflow machinery. |
@samueltardieu does that make sense? I hope that makes sense. Basically, I don't want to implement variable-bound-recursion-detection without the necessary dataflow machinery; it's going to be a pain and it's going to be a lot less complete than it would be otherwise. It should probably be noted somewhere in the lint docs that this implementation only touches direct fn call expressions. I could open up an issue as well noting down the code paths that a more sophisticated recursion analysis could catch, and write down exactly what such a lint is currently blocked on. |
Checklist:
.stderr
file)cargo test
passes locallycargo dev update_lints
cargo dev fmt
changelog: new lint: [
direct_recursion
]Fixes #428
After we're done with this, I'll open a follow-up issue for the indirect recursion lint