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

Add lint for comparing floats in an array #4343

Conversation

briankabiro
Copy link
Contributor

Finishes #4277

changelog: none

clippy_lints/src/misc.rs Outdated Show resolved Hide resolved
clippy_lints/src/misc.rs Outdated Show resolved Hide resolved
@briankabiro briankabiro force-pushed the add-lint-for-float-in-array-comparison branch from 99445f9 to 1de416b Compare August 13, 2019 18:45
@briankabiro briankabiro changed the title Add lint when comparing floats in an array Add lint for comparing floats in an array Aug 13, 2019
@briankabiro briankabiro marked this pull request as ready for review August 13, 2019 19:42
@flip1995 flip1995 added the S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) label Aug 14, 2019
@@ -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(_))
Copy link
Contributor Author

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.

Copy link
Member

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(_):

Suggested change
matches!(value, ty::Array(_ty, _)) || matches!(value, ty::Float(_))
matches!(value, ty::Array(ty, _)) && matches!(ty.node, ty::Float(_)) || matches!(value, ty::Float(_))

Copy link
Member

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 &Floats shouldn't be compared either.

Copy link
Contributor Author

@briankabiro briankabiro Aug 22, 2019

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.

Copy link
Member

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.

Copy link
Contributor Author

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.

error: strict comparison of f32 or f64
--> $DIR/eq_op.rs:25:5
|
LL | ([1] != [1]);
Copy link
Member

@flip1995 flip1995 Aug 15, 2019

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.

@briankabiro briankabiro force-pushed the add-lint-for-float-in-array-comparison branch from 1de416b to dc53b28 Compare August 27, 2019 14:27
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(_))
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
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(_))

Copy link
Contributor Author

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?

Copy link
Member

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.

Copy link
Contributor Author

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!

@briankabiro briankabiro force-pushed the add-lint-for-float-in-array-comparison branch from dc53b28 to 11197c5 Compare September 17, 2019 09:08
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.

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(_));
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 we also have to walk_ptrs_ty on arr_ty, so that Arrays of &floats also get linted.

Copy link
Contributor Author

@briankabiro briankabiro Sep 17, 2019

Choose a reason for hiding this comment

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

On it 🏃

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'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];
Copy link
Member

@flip1995 flip1995 Sep 20, 2019

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]?

Playground

Copy link
Contributor Author

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]);
Copy link
Member

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, ...)

@bors
Copy link
Collaborator

bors commented Sep 26, 2019

☔ The latest upstream changes (presumably #4580) made this pull request unmergeable. Please resolve the merge conflicts.

@flip1995 flip1995 added A-lint Area: New lints and removed A-lint Area: New lints labels Nov 25, 2019
@flip1995
Copy link
Member

flip1995 commented Mar 9, 2020

I'll set this to S-inactive-closed, since someone else want to take up this issue. Thanks @briankabiro for doing the initial work!

@flip1995 flip1995 closed this Mar 9, 2020
@flip1995 flip1995 added S-inactive-closed Status: Closed due to inactivity and removed S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) labels Mar 9, 2020
@jonboh
Copy link
Contributor

jonboh commented Oct 10, 2023

@rustbot label -S-inactive-closed

@rustbot rustbot removed the S-inactive-closed Status: Closed due to inactivity label Oct 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants