-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
New lint: manual_ok_err #13740
New lint: manual_ok_err #13740
Conversation
r? @Alexendoo rustbot has assigned @Alexendoo. Use |
302f535
to
e9ea195
Compare
|
0e256f7
to
3826c02
Compare
69d6a3b
to
a5d134c
Compare
(the latest push is a rebase on master) |
ef3cb7d
to
c43abbf
Compare
r? @y21 |
More maintainer roulette r? @blyxyas |
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.
Everything seems to be correct, and it seems to be a very useful lint. I think it has some bright future! (Some clarity nits were found)
&& let Some((idx, is_ok)) = arms.iter().enumerate().find_map(|(arm_idx, arm)| { | ||
if let Some((is_ok, ident)) = is_ok_or_err(cx, arm.pat) | ||
&& is_some_ident(cx, arm.body, ident) | ||
{ | ||
Some((arm_idx, is_ok)) | ||
} else { | ||
None | ||
} | ||
}) |
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.
A refactoring or comment would help the clarity of this fragment!
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.
Comment added
c43abbf
to
7e3a863
Compare
The FCP just opened, we'll wait a few days and check that everything's alright. I like the idea of this lint 👍 |
Does the current implementation consider const code? It probably shouldn't lint in those cases. |
7e3a863
to
3a88396
Compare
It doesn't lint in const code (checked in |
} | ||
|
||
fn main() { | ||
let _ = match funcall() { |
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.
Not sure if the lint logic accounts for this but I think it would be good to have a test for coercions in the Some
match arm that wouldn't work with .ok()
. Something like
let s: Option<&dyn Any> = match Ok::<_, ()>(&1) {
Ok(v) => Some(v),
_ => None
};
(Can't come up with a better case rn but this particular FP had been reported for similar lints in the past)
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.
Indeed. I've added a check that the type is the same inside the Result
variant we keep and the Option
. I've also rebased this patch because I added a new function to clippy_utils/src/ty/mod.rs
which has been renamed from ty.rs
in the meantime.
PatKind::Wild | PatKind::Path(..) if can_be_wild => true, | ||
PatKind::TupleStruct(..) | PatKind::Struct(..) | PatKind::Binding(_, _, _, None) => true, |
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.
Shouldn't PatKind::Binding
be part of the first arm given that it is basically a wildcard pattern? E.g. this gets linted, but .ok()
is not equivalent there
match Ok::<_, ()>(&1) {
_x => None,
Ok(v) => Some(v),
};
(Not sure why anyone would write code like this but there seems to be some logic for handling it in the lint and some similar looking tests, so thought I'd comment on that)
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.
Good catch. Fixed.
let _ = match funcall() { | ||
Err(_) | Ok(3) => None, | ||
Ok(v) => Some(v), | ||
}; |
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.
Can you add a similar test case where the error type is infallible (so no |
pattern is needed to create overlapping patterns)?
match Ok::<_, std::convert::Infallible>(1) {
Ok(3) => None,
Ok(v) => Some(v)
};
Reading through the current is_variant_or_wildcard
implementation I think this gets linted even though it's not equivalent
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.
Good catch again, I hadn't thought of this one, fixed.
3a88396
to
e602a6b
Compare
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.
LGTM, thanks! ❤️
e602a6b
to
4a69d0d
Compare
changelog: [
manual_ok_err
]: new lintDetect manual implementations of
.ok()
or.err()
, as inwhich can be replaced by
This pattern was detected in the wild in the Rust reimplementation of coreutils: uutils/coreutils#6886 (review)