-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Add undocumented_may_panic_call lint
#15969
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?
Conversation
This comment has been minimized.
This comment has been minimized.
|
r? blyxyas |
|
|
bab87c9 to
4bb7fdc
Compare
This comment has been minimized.
This comment has been minimized.
| /// #[clippy::may_panic] | ||
| /// fn my_panicable_func(n: u32) { | ||
| /// if n % 2 == 0 { | ||
| /// panic!("even number not allowed") |
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.
Little typo in the documentation =^w^=
| /// panic!("even number not allowed") | |
| /// panic!("even numbers are not allowed") |
| /// #[clippy::may_panic] | ||
| /// fn my_panicable_func(n: u32) { | ||
| /// if n % 2 == 0 { | ||
| /// panic!("even number not allowed") |
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.
| /// panic!("even number not allowed") | |
| /// panic!("even numbers are not allowed") |
| if get_unique_attr(cx.sess(), cx.tcx.get_all_attrs(def_id), sym::may_panic).is_some() { | ||
| return true; | ||
| } | ||
|
|
||
| self.may_panic_def_ids.contains(&def_id) |
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.
| if get_unique_attr(cx.sess(), cx.tcx.get_all_attrs(def_id), sym::may_panic).is_some() { | |
| return true; | |
| } | |
| self.may_panic_def_ids.contains(&def_id) | |
| get_unique_attr(cx.sess(), cx.tcx.get_all_attrs(def_id), sym::may_panic).is_some() || self.may_panic_def_ids.contains(&def_id) |
| && call_line.line > 0 | ||
| && let Some(src) = call_line.sf.src.as_deref() |
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.
We need to handle macros (the most difficult portion in the art of lint-making), I've been thinking about this and I think that the best option is to permit this two scenarios:
- The macro handles the comment, this is what's going on currently.
- The callsite of the macro handles the comment.
So, for macro calls that are not justified in-macro, the user will need to write a PANIC comment.
So, we'll need to recurse through the HIR parents, check if we're in a macro, and if we're not, check for the comment.
The functions to check if we're in a macro are is_from_proc_macro, in_external_macro and from_expansion
|
|
||
| // Panic: This is safe, just trust me. | ||
| let _ = t.trait_panic_method(); | ||
| } |
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.
Some more testing would be much appreciated, note that tests also test that every other lint is working correctly, so doing some extremely weird syntax (and, if it's too weird, explaining where it should lint) is very beneficial for our test suite.
Many of the bugs we receive are from extremely niche use cases, so testing for those before a lint goes into a release is very beneficial.
| } | |
| #[allow(clippy::needless_bool, clippy::unnecessary_operation)] | |
| fn weird_exprs(t: &dyn MyTrait) { | |
| // The Panic comment should be in the second If statement | |
| if if if true { true } else { false } { | |
| t.trait_panic_method() == 0 | |
| //~^ undocumented_may_panic_call | |
| } else { | |
| false | |
| } { | |
| true | |
| } else { | |
| false | |
| }; | |
| if if if true { true } else { false } { | |
| // PANIC: This is safe! | |
| t.trait_panic_method() == 0 | |
| } else { | |
| false | |
| } { | |
| true | |
| } else { | |
| false | |
| }; | |
| #[clippy::may_panic] | |
| fn panic<T>(val: T) -> T {val} | |
| macro_rules! mac { | |
| ($t:tt) => ($t) | |
| } | |
| // Panic comment should go on the line before the panic() function | |
| async {{};({(u8::max)( | |
| // PANIC: Safe! | |
| panic(1)+mac!(2),mac!(2))}); | |
| }; | |
| } | |
| macro_rules! may_panic { | |
| () => {dangerous(1)} | |
| } | |
| fn on_macro() { | |
| // PANIC: Hi | |
| may_panic!(); | |
| // REVIEWER: ^^^^^^^ This currently doesn't work! See other comments | |
| } |
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.
Great first patch! Sorry for the delayed response, I took a vacation right after starting to review this (in fact, if you check the comment date for those first review comments, you'll see that I made them 2 weeks ago)
|
@blyxyas Thanks for the review! It was my turn to be on vacation when I got it haha, but I'll be working on an update here over the next few days :) |
Checks for calls to functions marked with `#[clippy::may_panic]` or configured in `may-panic-functions` that lack a `// Panic:` comment documenting why the panic is acceptable. changelog: new_lint: [`undocumented_may_panic_call`]
- Fixing typos - Code cleanup and more tests - Adding handling and tests for all kinds of macros
4bb7fdc to
ac41ba9
Compare
|
This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
|
@blyxyas I had to rebase and |
Checks for calls to functions marked with
#[clippy::may_panic]or configured inmay-panic-functionsthat lack a// Panic:comment documenting why the panic is acceptable.fixes #15861
changelog: new_lint: [
undocumented_may_panic_call]