-
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
Add lint for comparing floats in an array #4343
Add lint for comparing floats in an array #4343
Conversation
99445f9
to
1de416b
Compare
clippy_lints/src/misc.rs
Outdated
@@ -519,7 +519,8 @@ fn is_signum(cx: &LateContext<'_, '_>, expr: &Expr) -> bool { | |||
} | |||
|
|||
fn is_float(cx: &LateContext<'_, '_>, expr: &Expr) -> bool { | |||
matches!(walk_ptrs_ty(cx.tables.expr_ty(expr)).sty, ty::Float(_)) | |||
let value = &walk_ptrs_ty(cx.tables.expr_ty(expr)).sty; | |||
matches!(value, ty::Array(_ty, _)) || matches!(value, ty::Float(_)) |
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, @flip1995. All done with the update. This is what I have now.
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.
You also have to match _ty.node
to Float(_)
:
matches!(value, ty::Array(_ty, _)) || matches!(value, ty::Float(_)) | |
matches!(value, ty::Array(ty, _)) && matches!(ty.node, ty::Float(_)) || matches!(value, ty::Float(_)) |
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.
You may also want to walk_ptrs_ty(ty)
, since an Array
of &Float
s shouldn't be compared either.
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 @flip1995.
I think I understand what I'm supposed to do.
matches!(value, ty::Array(ty, _))
matches an array
matches!(ty.node, ty::Float(_))
is to match when the value inside the array is a Float.
The issue I'm having right now is getting the second part, checking if it is a Float.
When I match against ty.node
, I get this error: expected value, found module ty
This is what I get when print the value of walk_ptrs_ty
, when it's an array.
Array(u8, Const { ty: usize, val: Scalar(0x0000000000000004) })
I'm thinking that I have to match against the value inside the Const
struct.
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.
You can ignore the Const
struct, since it is only the length of the array. The Rust type system already forbids the comparison of two arrays with different lengths, so we don't have to take care about that.
You have to match the u8
. Note, that the u8
is only displayed because of the pretty printing of types. In fact it is just another ty::Ty
.
On the error message: You get this, because you shadow the import of ty
with the variable name ty
. Renaming the variable ty
with arr_ty
or similar should solve this.
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. I will get to work on it.
tests/ui/eq_op.stderr
Outdated
error: strict comparison of f32 or f64 | ||
--> $DIR/eq_op.rs:25:5 | ||
| | ||
LL | ([1] != [1]); |
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.
These are integers and shouldn't trigger the lint. See comment above, on how to fix this.
1de416b
to
dc53b28
Compare
clippy_lints/src/misc.rs
Outdated
matches!(walk_ptrs_ty(cx.tables.expr_ty(expr)).sty, ty::Float(_)) | ||
let value = &walk_ptrs_ty(cx.tables.expr_ty(expr)).sty; | ||
|
||
matches!(value, ty::Array(arr_ty, _)) && matches!(value, ty::Float(_)) || matches!(value, ty::Float(_)) |
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.
matches!(value, ty::Array(arr_ty, _)) && matches!(value, ty::Float(_)) || matches!(value, ty::Float(_)) | |
matches!(value, ty::Array(arr_ty, _)) && matches!(&walk_ptrs_ty(arr_ty).sty, ty::Float(_)) || matches!(value, ty::Float(_)) |
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.
Unfortunately, getting an error that:
`arr_ty` is not found in this scope
Could it be an issue with the macro?
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.
In that case you have to write the match yourself. The macro seems to open a new scope for the variables.
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. Was caught up this week, didn't get the chance to take a look at this further.
Going to resume next week!
dc53b28
to
11197c5
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.
Can you add tests, please?
let value = &walk_ptrs_ty(cx.tables.expr_ty(expr)).sty; | ||
|
||
if let ty::Array(arr_ty, _) = value { | ||
return matches!(arr_ty.sty, ty::Float(_)); |
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 think we also have to walk_ptrs_ty
on arr_ty
, so that Arrays of &float
s also get linted.
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.
On it 🏃
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 having a bit of an issue getting the walk_ptrs_ty
to work with arr_ty
; I have updated the tests in the meanwhile. You can have a look if I'm going in the right direction so far.
@@ -77,6 +77,13 @@ fn main() { | |||
|
|||
assert_eq!(a, b); // no errors | |||
|
|||
let a1: [f32; 1] = [0.0]; | |||
let a2: [f32; 1] = [1.1]; |
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.
Could you also add a test for the type [&f32; 1]
?
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 the help.
let a1: [f32; 1] = [0.0]; | ||
let a2: [f32; 1] = [1.1]; | ||
|
||
assert_eq!(a1[0], a2[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.
If we want to do it right, this should not trigger the lint, since everything in a1
ist constant 0.0
, so a comparison is ok here.
On a more general note, this enhancement needs more tests like the base case of comparing floats. (Comparing arrays of constant 0.0, constant {NEG_}INFINITY, ...)
☔ The latest upstream changes (presumably #4580) made this pull request unmergeable. Please resolve the merge conflicts. |
I'll set this to |
@rustbot label -S-inactive-closed |
Finishes #4277
changelog: none