Skip to content
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

Added a lint which corrects expressions like (a - b) < f32::EPSILON, according to #5819 #5952

Merged
merged 2 commits into from
Aug 25, 2020

Conversation

1c3t3a
Copy link
Contributor

@1c3t3a 1c3t3a commented Aug 24, 2020

Fixes #5819
changelog: none

@rust-highfive
Copy link

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @Manishearth (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Aug 24, 2020
// check if expr is a binary expression with a lt or gt operator
if let ExprKind::Binary(op, ref left, ref right) = expr.kind {
match op.node {
BinOpKind::Lt => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can be done as if let ExprKind::Binary(Lt | Rt, left, right) ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if I get this wrong, but I still need to differentiate between BinOpKind::Lt and BinOpKind::Gt. If I would use something like
if let ExprKind::Binary( Spanned { node: BinOpKind::Lt | BinOpKind::Gt, .. }, left, right, ) = ...
Then I would still need to sort out whether my Operator is < or >. Or am I wrong?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh sorry, you're absolutely right


// right hand side matches either f32::EPSILON or f64::EPSILON
if let ExprKind::Path(ref epsilon_path) = rhs.kind;
if match_qpath(epsilon_path, &["f32", "EPSILON"]) || match_qpath(epsilon_path, &["f64", "EPSILON"]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Manishearth
Copy link
Member

@bors r+

thanks!

@bors
Copy link
Collaborator

bors commented Aug 25, 2020

📌 Commit 179df0b has been approved by Manishearth

@bors
Copy link
Collaborator

bors commented Aug 25, 2020

⌛ Testing commit 179df0b with merge 44490ab...

bors added a commit that referenced this pull request Aug 25, 2020
Added a lint which corrects expressions like (a - b) < f32::EPSILON, according to #5819

Fixes #5819
changelog: none
@bors
Copy link
Collaborator

bors commented Aug 25, 2020

💔 Test failed - checks-action_test

@1c3t3a
Copy link
Contributor Author

1c3t3a commented Aug 25, 2020

Mh.. looks like an error with the latest nightly version. Should I fix this by removing the #![feature(range_is_empty)] in ui/len_zero_ranges.rs or do we wait?

@flip1995 flip1995 added S-waiting-on-bors Status: The marked PR was approved and is only waiting bors and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels Aug 25, 2020
@flip1995
Copy link
Member

Let's wait. I'll fix this in a separate PR.

@flip1995
Copy link
Member

@bors retry

@bors
Copy link
Collaborator

bors commented Aug 25, 2020

⌛ Testing commit 179df0b with merge f901559...

@bors
Copy link
Collaborator

bors commented Aug 25, 2020

☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test
Approved by: Manishearth
Pushing f901559 to master...

Copy link
Member

@flip1995 flip1995 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Post merge review, since I read something in your discussion in the issue that bugged me.

--> $DIR/float_equality_without_abs.rs:13:13
|
LL | let _ = (a - b) < f32::EPSILON;
| ^^^^^^^^^^^^^^^^^^^^^^ help: add `.abs()`: `(a - b).abs()`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This suggestion doesn't work. If applied, this will transform the code like this:

let _ = (a - b) < f32::EPSILON; // before
let _ = (a - b).abs(); // after

A better way to do this would be to use span_lint_and_then and then use the db.span_suggestion to only add the above suggestion to the span of (a - b).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh you're right! Thank you @flip1995 and sorry that I didn't see that earlier! I've corrected it on my own fork. Should I open a new PR for this fix? I've also started to use utils::Sugg. But I had some issues while parsing the expression, the simple way of

let suggestion = format!("{}.abs()", sugg::Sugg::hir(cx, &lhs, "..").maybe_par());

always brought up doubled parentheses. E.g. (a - b) -> ((a - b)). That's why I took a longer way and assembled the suggestion by myself. Maybe you could have a look on the code, it's all in this commit here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The linked commit looks good to me.

Yes please open a new PR about this!

Comment on lines +87 to +98
// get the snippet string
let lhs_string = snippet(
cx,
lhs.span,
"(...)",
);
// format the suggestion
let suggestion = if lhs_string.starts_with('(') {
format!("{}.abs()", lhs_string)
} else {
format!("({}).abs()", lhs_string)
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@1c3t3a If you want to further improve this code, you can use utils::Sugg here, that will take care about this automatically.

bors added a commit that referenced this pull request Aug 26, 2020
Corrects the float_equality_without_abs lint

Fixes an issue in the `float_equality_without_abs` lint. The lint suggestion was configured in a way that it lints the whole error and not just the subtraction part. In the current configuration the lint would suggest to change the expression in a wrong way, e.g.
```rust
let _ = (a - b) < f32::EPSILON; // before
let _ = (a - b).abs(); // after
```
This was dicovered by @flip1995. (See discussion of PR #5952).

Also the suggestion is now formatted via `utils::sugg`.
changelog: none
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: The marked PR was approved and is only waiting bors
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Lints (a - b) < f32::EPSILON in favor of (a - b).abs() < f32::EPSILON
5 participants