-
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_midpoint
#13851
base: master
Are you sure you want to change the base?
New lint: manual_midpoint
#13851
Conversation
906f3bd
to
1561476
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.
❤️ Thanks for working on it, appreciate it.
Left a few remarks/nits.
cx, | ||
MANUAL_MIDPOINT, | ||
expr.span, | ||
"manual implementation of `midpoint`", |
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.
"manual implementation of `midpoint`", | |
"manual implementation of `midpoint` which can overflow", |
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.
I'm reluctant to add this on the lint message, because this particular use may well never overflow depending on the context. This is appropriate for the lint short description though, I'll add it there. What do you think?
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 should add it to the lint short description, but I still think we should mention it in the main message as it's the main issue (not the fact that it's a manual implementation). We could reduce the assertion by saying "which may overflow" (instead of "can").
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.
Any addition may overflow, and we do not suggest using .checked_add()
. I'll let other weigh in, but I'm not comfortable saying "which may overflow" on (a + b) / 2
if a
and b
are indices in a vector for example, they will never overflow as they will be nowhere near usize::MAX/2
for any realistic vector.
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 + b) / 2
ifa
andb
are indices in a vector for example
u8::MAX = 255
, u16::MAX = 65536
are fairly realistic numbers to me (which could be indices of custom containers).
they will never overflow as they will be nowhere near
usize::MAX/2
for any realistic vector.
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.
I was specifically talking about the usize
case which is used to index a vector. And let's not confuse the issue: I'm not trying to argue that we should not lint, we will, only that I am not comfortable saying that a particular computation may overflow.
I couldn't find lints that warn about the potential risk when linting an expression if the risk is remote or non-existing for this particular expression, even though they still lint to make it clearer and safer should this code be changed later.
tests/ui/manual_midpoint.stderr
Outdated
--> tests/ui/manual_midpoint.rs:12:13 | ||
| | ||
LL | let _ = (f + 5.0) / 2.0; | ||
| ^^^^^^^^^^^^^^^ help: use instead: `f32::midpoint(f, 5.0)` |
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.
I don't if it's in Clippy customs but would be possible to add a help linking to the documentation, something like this (which rustc
does to further guide the user):
help: for more information visit <https://doc.rust-lang.org/nightly/std/primitive.u32.html#method.midpoint>
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 is done only for niche or complex situations in the existing codebase, such as implementing a local trait for a foreign type (orphan rule).
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.
There's a first time for everything. :-)
More seriously, I'm fine if the link it's not included.
let mut app = Applicability::MachineApplicable; | ||
let left_sugg = Sugg::hir_with_applicability(cx, ll_expr, "..", &mut app); | ||
let right_sugg = Sugg::hir_with_applicability(cx, lr_expr, "..", &mut app); | ||
let sugg = format!("{left_ty}::midpoint({left_sugg}, {right_sugg})"); |
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.
Interesting choice of form, I would have probably use the method syntax (ie. .midpoint(..)
) instead, as to not have to much shifts from the original code, but that works as well.
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.
I feel that linting (a + b) / 2
as a.midpoint(b)
introduces an asymmetry between a
and b
while u32::midpoint(a, b)
doesn't. But I'm not opposed to this change.
What do others think? Please upvote if you prefer a.midpoint(b)
and downvote if you prefer u32::midpoint(a, b)
.
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.
I can't pick between the 2 because the first one is more convenirnt but the second one is more readable...
Well, by writing this comment I realized I prefer more readable code so let's go for 2.
657e651
to
6e01b0d
Compare
6e01b0d
to
8fc52b4
Compare
changelog: [
manual_midpoint
]: new lintCloses #13849