2022-02-08 16:45:52 +00:00
|
|
|
#![warn(clippy::eq_op)]
|
|
|
|
#![allow(clippy::double_parens, clippy::identity_op, clippy::nonminimal_bool)]
|
2022-10-21 17:46:47 +00:00
|
|
|
#![allow(clippy::suspicious_xor_used_as_pow)]
|
2022-02-08 16:45:52 +00:00
|
|
|
|
2015-04-30 09:48:43 +00:00
|
|
|
fn main() {
|
2015-08-11 18:22:20 +00:00
|
|
|
// simple values and comparisons
|
2022-02-08 16:45:52 +00:00
|
|
|
let _ = 1 == 1;
|
2023-07-28 19:35:48 +00:00
|
|
|
//~^ ERROR: equal expressions as operands to `==`
|
|
|
|
//~| NOTE: `-D clippy::eq-op` implied by `-D warnings`
|
2022-02-08 16:45:52 +00:00
|
|
|
let _ = "no" == "no";
|
2023-07-28 19:35:48 +00:00
|
|
|
//~^ ERROR: equal expressions as operands to `==`
|
2015-08-11 18:22:20 +00:00
|
|
|
// even though I agree that no means no ;-)
|
2022-02-08 16:45:52 +00:00
|
|
|
let _ = false != false;
|
2023-07-28 19:35:48 +00:00
|
|
|
//~^ ERROR: equal expressions as operands to `!=`
|
2022-02-08 16:45:52 +00:00
|
|
|
let _ = 1.5 < 1.5;
|
2023-07-28 19:35:48 +00:00
|
|
|
//~^ ERROR: equal expressions as operands to `<`
|
2022-02-08 16:45:52 +00:00
|
|
|
let _ = 1u64 >= 1u64;
|
2023-07-28 19:35:48 +00:00
|
|
|
//~^ ERROR: equal expressions as operands to `>=`
|
2023-06-30 16:39:33 +00:00
|
|
|
let x = f32::NAN;
|
|
|
|
let _ = x != x;
|
2023-07-28 19:35:48 +00:00
|
|
|
//~^ ERROR: equal expressions as operands to `!=`
|
|
|
|
//~| NOTE: if you intended to check if the operand is NaN, use `.is_nan()` instead
|
2015-08-11 18:22:20 +00:00
|
|
|
|
2015-08-13 07:44:03 +00:00
|
|
|
// casts, methods, parentheses
|
2022-02-08 16:45:52 +00:00
|
|
|
let _ = (1u32 as u64) & (1u32 as u64);
|
2023-07-28 19:35:48 +00:00
|
|
|
//~^ ERROR: equal expressions as operands to `&`
|
2022-02-08 16:45:52 +00:00
|
|
|
#[rustfmt::skip]
|
|
|
|
{
|
|
|
|
let _ = 1 ^ ((((((1))))));
|
2023-07-28 19:35:48 +00:00
|
|
|
//~^ ERROR: equal expressions as operands to `^`
|
2022-02-08 16:45:52 +00:00
|
|
|
};
|
2015-08-11 18:22:20 +00:00
|
|
|
|
|
|
|
// unary and binary operators
|
2022-02-08 16:45:52 +00:00
|
|
|
let _ = (-(2) < -(2));
|
2023-07-28 19:35:48 +00:00
|
|
|
//~^ ERROR: equal expressions as operands to `<`
|
2022-02-08 16:45:52 +00:00
|
|
|
let _ = ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1));
|
2023-07-28 19:35:48 +00:00
|
|
|
//~^ ERROR: equal expressions as operands to `==`
|
|
|
|
//~| ERROR: equal expressions as operands to `&`
|
|
|
|
//~| ERROR: equal expressions as operands to `&`
|
2022-02-08 16:45:52 +00:00
|
|
|
let _ = (1 * 2) + (3 * 4) == 1 * 2 + 3 * 4;
|
2023-07-28 19:35:48 +00:00
|
|
|
//~^ ERROR: equal expressions as operands to `==`
|
2015-08-11 18:22:20 +00:00
|
|
|
|
|
|
|
// various other things
|
2022-02-08 16:45:52 +00:00
|
|
|
let _ = ([1] != [1]);
|
2023-07-28 19:35:48 +00:00
|
|
|
//~^ ERROR: equal expressions as operands to `!=`
|
2022-02-08 16:45:52 +00:00
|
|
|
let _ = ((1, 2) != (1, 2));
|
2023-07-28 19:35:48 +00:00
|
|
|
//~^ ERROR: equal expressions as operands to `!=`
|
2022-02-08 16:45:52 +00:00
|
|
|
let _ = vec![1, 2, 3] == vec![1, 2, 3]; //no error yet, as we don't match macros
|
2015-08-21 10:26:03 +00:00
|
|
|
|
|
|
|
// const folding
|
2022-02-08 16:45:52 +00:00
|
|
|
let _ = 1 + 1 == 2;
|
2023-07-28 19:35:48 +00:00
|
|
|
//~^ ERROR: equal expressions as operands to `==`
|
2022-02-08 16:45:52 +00:00
|
|
|
let _ = 1 - 1 == 0;
|
2023-07-28 19:35:48 +00:00
|
|
|
//~^ ERROR: equal expressions as operands to `==`
|
|
|
|
//~| ERROR: equal expressions as operands to `-`
|
2017-02-08 13:58:07 +00:00
|
|
|
|
2022-02-08 16:45:52 +00:00
|
|
|
let _ = 1 - 1;
|
2023-07-28 19:35:48 +00:00
|
|
|
//~^ ERROR: equal expressions as operands to `-`
|
2022-02-08 16:45:52 +00:00
|
|
|
let _ = 1 / 1;
|
2023-07-28 19:35:48 +00:00
|
|
|
//~^ ERROR: equal expressions as operands to `/`
|
2022-02-08 16:45:52 +00:00
|
|
|
let _ = true && true;
|
2023-07-28 19:35:48 +00:00
|
|
|
//~^ ERROR: equal expressions as operands to `&&`
|
2016-02-03 19:42:05 +00:00
|
|
|
|
2022-02-08 16:45:52 +00:00
|
|
|
let _ = true || true;
|
2023-07-28 19:35:48 +00:00
|
|
|
//~^ ERROR: equal expressions as operands to `||`
|
2016-01-30 19:10:14 +00:00
|
|
|
|
2016-11-16 20:57:56 +00:00
|
|
|
let a: u32 = 0;
|
|
|
|
let b: u32 = 0;
|
2016-03-24 15:11:38 +00:00
|
|
|
|
2022-02-08 16:45:52 +00:00
|
|
|
let _ = a == b && b == a;
|
2023-07-28 19:35:48 +00:00
|
|
|
//~^ ERROR: equal expressions as operands to `&&`
|
2022-02-08 16:45:52 +00:00
|
|
|
let _ = a != b && b != a;
|
2023-07-28 19:35:48 +00:00
|
|
|
//~^ ERROR: equal expressions as operands to `&&`
|
2022-02-08 16:45:52 +00:00
|
|
|
let _ = a < b && b > a;
|
2023-07-28 19:35:48 +00:00
|
|
|
//~^ ERROR: equal expressions as operands to `&&`
|
2022-02-08 16:45:52 +00:00
|
|
|
let _ = a <= b && b >= a;
|
2023-07-28 19:35:48 +00:00
|
|
|
//~^ ERROR: equal expressions as operands to `&&`
|
2017-02-08 13:58:07 +00:00
|
|
|
|
2016-01-30 19:10:14 +00:00
|
|
|
let mut a = vec![1];
|
2022-02-08 16:45:52 +00:00
|
|
|
let _ = a == a;
|
2023-07-28 19:35:48 +00:00
|
|
|
//~^ ERROR: equal expressions as operands to `==`
|
2022-02-08 16:45:52 +00:00
|
|
|
let _ = 2 * a.len() == 2 * a.len(); // ok, functions
|
|
|
|
let _ = a.pop() == a.pop(); // ok, functions
|
2017-04-28 15:07:39 +00:00
|
|
|
|
2017-12-22 18:37:44 +00:00
|
|
|
check_ignore_macro();
|
2018-03-23 18:26:52 +00:00
|
|
|
|
|
|
|
// named constants
|
|
|
|
const A: u32 = 10;
|
|
|
|
const B: u32 = 10;
|
|
|
|
const C: u32 = A / B; // ok, different named constants
|
|
|
|
const D: u32 = A / A;
|
2023-07-28 19:35:48 +00:00
|
|
|
//~^ ERROR: equal expressions as operands to `/`
|
2017-12-22 18:37:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! check_if_named_foo {
|
2022-02-08 16:45:52 +00:00
|
|
|
($expression:expr) => {
|
2017-12-22 18:37:44 +00:00
|
|
|
if stringify!($expression) == "foo" {
|
|
|
|
println!("foo!");
|
|
|
|
} else {
|
|
|
|
println!("not foo.");
|
|
|
|
}
|
2022-02-08 16:45:52 +00:00
|
|
|
};
|
2017-12-22 18:37:44 +00:00
|
|
|
}
|
|
|
|
|
2020-01-22 07:48:00 +00:00
|
|
|
macro_rules! bool_macro {
|
|
|
|
($expression:expr) => {
|
|
|
|
true
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-12-22 18:37:44 +00:00
|
|
|
fn check_ignore_macro() {
|
|
|
|
check_if_named_foo!(foo);
|
2020-01-22 07:48:00 +00:00
|
|
|
// checks if the lint ignores macros with `!` operator
|
2022-02-08 16:45:52 +00:00
|
|
|
let _ = !bool_macro!(1) && !bool_macro!("");
|
2015-04-30 09:48:43 +00:00
|
|
|
}
|
add suspicious_operation_groupings lint
run `cargo dev new_lint --category correctness --name suspicious_chained_operators --pass early`
add (currently failing) tests for suspicious_chained_operators
add some tests to answer a question that came up during implementation
write usage code for functions we'll need to find or create
Complete left-right tracking TODO
get it compiling with several `todo!` invocations.
refactor to a set of incomplete functions that don't expect to be able to edit a `Span`
create placeholder for `suggestion_with_swapped_ident` function and correct some comments
add `inside_larger_boolean_expression` test
fill out `get_ident` and `suggestion_with_swapped_ident`
Implementi the `IdentIter`
start on implementing the `IdentIter`
handle the `ExprKind::Path` case in `IdentIter`
on second thought, make the iterator type dynamic so we don't need an explicit type for each one we will need
handle `ExprKind::MacCall` in `IdentIter`
Try handling `box x` expressions
restructure `IdentIter`
set `self.done` when returning `None`
Handle `ExprKind::Array`
reduce duplication with a macro that we expect to use several more times
handle ExprKind::Call
add `new_p` convenience method
handle `MethodCall`
handle `Tup` and `Binary`
handle `Unary`
simplify by not returning an additional `Expr` from the `IdentIter`
add cross product test against false positives
rename suspicious_chained_operators to suspicious_operation_groupings within files
For the record, the exact commands run were:
find . -type f -name "*.md" -exec sed -i 's/suspicious_chained_operators/suspicious_operation_groupings/g' {} +
find . -type f -name "*.rs" -exec sed -i 's/suspicious_chained_operators/suspicious_operation_groupings/g' {} +
find . -type f -name "*.rs" -exec sed -i 's/SUSPICIOUS_CHAINED_OPERATORS/SUSPICIOUS_OPERATION_GROUPINGS/g' {} +
find . -type f -name "*.rs" -exec sed -i 's/SuspiciousChainedOperators/SuspiciousOperationGroupings/g' {} +
Also:
rename file to match module name
rename test file to match lint name
start implementing `IdentDifference` creation
add `IdentIter` utility
use `ident_iter::IdentIter`
fix bug in `suggestion_with_swapped_ident`
add `inside_if_statements` test
implement `Add` `todo`s
register `SuspiciousOperationGroupings` lint pass
fill in `chained_binops`, and fill in a stopgap version of `ident_difference_expr`, but then notice that the lint does not seem to ever be run in the tests
run `cargo dev update_lints` and not that the `suspicious_operation_groupings` lint still does not seem to be run
fix base index incrementing bug
fix paired_identifiers bug, and remove ident from `Single`
change help prefix and note our first successful lint messages!
add odd_number_of_pairs test
get the `non_boolean_operators` test passing, with two copies of the error message
extract `is_useless_with_eq_exprs` so we can know when `eq_op` will already handle something
add `not_caught_by_eq_op` tests since `s1.b * s1.b` was (reasonably) not caught by `eq_op`
cover the case where the change should be made on either side of the expression with `not_caught_by_eq_op` tests
produce the expected suggestion on the `not_caught_by_eq_op_middle_change_left` test
confirm that the previous tests still pass and update references
fix early continue bug and get `not_caught_by_eq_op_middle_change_right` passing
note that `not_caught_by_eq_op_start` already passes
fix bugs based on misunderstanding of what `Iterator::skip` does, and note that `not_caught_by_eq_op_end` now passes
add several parens tests and make some of them pass
handle parens inside `chained_binops_helper` and note that this makes several tests pass
get `inside_larger_boolean_expression_with_unsorted_ops` test passing by extracting out `check_same_op_binops` function
also run `cargo dev fmt`
note that `inside_function_call` already passes
add another `if_statement` test
remove the matching op requirement, making `inside_larger_boolean_expression_with_unsorted_ops` pass
prevent non-change suggestions from being emitted
get the `Nested` tests passing, and remove apparently false note about eq_op
add a test to justify comment in `ident_difference_expr_with_base_location` but find that the failure mode seems different than expected
complete `todo` making `do_not_give_bad_suggestions_for_this_unusual_expr` pass and add some more tests that already pass
add test to `eq_op`
note that `inside_fn_with_similar_expression` already passes
fix `inside_an_if_statement` and note that it already passes
attempt to implement if statement extraction and notice that we don't seem to handle unary ops correctly
add `maximum_unary_minus_right_tree` test and make it pass
add two tests and note one of them passes
filter out unary operations in several places, and find that the issue seems to be that we don't currently recognize the error in `multiple_comparison_types_and_unary_minus` even so.
remove filtering that was causing bad suggestions
remove tests that were deemed too much for now
run `cargo dev fmt`
correct eq_op post-merge
fill out the description and delete debugging code
run `cargo dev update_lints`
update eq_op references
add parens to work around rustfmt issue #3666 and run rustfmt
https://github.com/rust-lang/rustfmt/issues/3666#issuecomment-714612257
update references after formatting
fix dogfood issues
fix multi-cursor edit
fix missed dogfood error
fix more dogfood pedantic issues, including function length
even more nesting
insert hidden definition of Vec3 so docs compile
add spaces to second struct def
reword test description comment
Co-authored-by: llogiq <bogusandre@gmail.com>
add local `use BinOpKind::*;`
Apply suggestions from code review
Co-authored-by: llogiq <bogusandre@gmail.com>
switch `SUSPICIOUS_OPERATION_GROUPINGS` to a style lint
run `cargo dev update_lints`
put both usages of `op_types` in the same closure to satisfy `borrowck`
fix compile error
2020-11-07 23:00:42 +00:00
|
|
|
|
|
|
|
struct Nested {
|
|
|
|
inner: ((i32,), (i32,), (i32,)),
|
|
|
|
}
|
|
|
|
|
|
|
|
fn check_nested(n1: &Nested, n2: &Nested) -> bool {
|
|
|
|
// `n2.inner.0.0` mistyped as `n1.inner.0.0`
|
|
|
|
(n1.inner.0).0 == (n1.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.2).0
|
2023-07-28 19:35:48 +00:00
|
|
|
//~^ ERROR: equal expressions as operands to `==`
|
add suspicious_operation_groupings lint
run `cargo dev new_lint --category correctness --name suspicious_chained_operators --pass early`
add (currently failing) tests for suspicious_chained_operators
add some tests to answer a question that came up during implementation
write usage code for functions we'll need to find or create
Complete left-right tracking TODO
get it compiling with several `todo!` invocations.
refactor to a set of incomplete functions that don't expect to be able to edit a `Span`
create placeholder for `suggestion_with_swapped_ident` function and correct some comments
add `inside_larger_boolean_expression` test
fill out `get_ident` and `suggestion_with_swapped_ident`
Implementi the `IdentIter`
start on implementing the `IdentIter`
handle the `ExprKind::Path` case in `IdentIter`
on second thought, make the iterator type dynamic so we don't need an explicit type for each one we will need
handle `ExprKind::MacCall` in `IdentIter`
Try handling `box x` expressions
restructure `IdentIter`
set `self.done` when returning `None`
Handle `ExprKind::Array`
reduce duplication with a macro that we expect to use several more times
handle ExprKind::Call
add `new_p` convenience method
handle `MethodCall`
handle `Tup` and `Binary`
handle `Unary`
simplify by not returning an additional `Expr` from the `IdentIter`
add cross product test against false positives
rename suspicious_chained_operators to suspicious_operation_groupings within files
For the record, the exact commands run were:
find . -type f -name "*.md" -exec sed -i 's/suspicious_chained_operators/suspicious_operation_groupings/g' {} +
find . -type f -name "*.rs" -exec sed -i 's/suspicious_chained_operators/suspicious_operation_groupings/g' {} +
find . -type f -name "*.rs" -exec sed -i 's/SUSPICIOUS_CHAINED_OPERATORS/SUSPICIOUS_OPERATION_GROUPINGS/g' {} +
find . -type f -name "*.rs" -exec sed -i 's/SuspiciousChainedOperators/SuspiciousOperationGroupings/g' {} +
Also:
rename file to match module name
rename test file to match lint name
start implementing `IdentDifference` creation
add `IdentIter` utility
use `ident_iter::IdentIter`
fix bug in `suggestion_with_swapped_ident`
add `inside_if_statements` test
implement `Add` `todo`s
register `SuspiciousOperationGroupings` lint pass
fill in `chained_binops`, and fill in a stopgap version of `ident_difference_expr`, but then notice that the lint does not seem to ever be run in the tests
run `cargo dev update_lints` and not that the `suspicious_operation_groupings` lint still does not seem to be run
fix base index incrementing bug
fix paired_identifiers bug, and remove ident from `Single`
change help prefix and note our first successful lint messages!
add odd_number_of_pairs test
get the `non_boolean_operators` test passing, with two copies of the error message
extract `is_useless_with_eq_exprs` so we can know when `eq_op` will already handle something
add `not_caught_by_eq_op` tests since `s1.b * s1.b` was (reasonably) not caught by `eq_op`
cover the case where the change should be made on either side of the expression with `not_caught_by_eq_op` tests
produce the expected suggestion on the `not_caught_by_eq_op_middle_change_left` test
confirm that the previous tests still pass and update references
fix early continue bug and get `not_caught_by_eq_op_middle_change_right` passing
note that `not_caught_by_eq_op_start` already passes
fix bugs based on misunderstanding of what `Iterator::skip` does, and note that `not_caught_by_eq_op_end` now passes
add several parens tests and make some of them pass
handle parens inside `chained_binops_helper` and note that this makes several tests pass
get `inside_larger_boolean_expression_with_unsorted_ops` test passing by extracting out `check_same_op_binops` function
also run `cargo dev fmt`
note that `inside_function_call` already passes
add another `if_statement` test
remove the matching op requirement, making `inside_larger_boolean_expression_with_unsorted_ops` pass
prevent non-change suggestions from being emitted
get the `Nested` tests passing, and remove apparently false note about eq_op
add a test to justify comment in `ident_difference_expr_with_base_location` but find that the failure mode seems different than expected
complete `todo` making `do_not_give_bad_suggestions_for_this_unusual_expr` pass and add some more tests that already pass
add test to `eq_op`
note that `inside_fn_with_similar_expression` already passes
fix `inside_an_if_statement` and note that it already passes
attempt to implement if statement extraction and notice that we don't seem to handle unary ops correctly
add `maximum_unary_minus_right_tree` test and make it pass
add two tests and note one of them passes
filter out unary operations in several places, and find that the issue seems to be that we don't currently recognize the error in `multiple_comparison_types_and_unary_minus` even so.
remove filtering that was causing bad suggestions
remove tests that were deemed too much for now
run `cargo dev fmt`
correct eq_op post-merge
fill out the description and delete debugging code
run `cargo dev update_lints`
update eq_op references
add parens to work around rustfmt issue #3666 and run rustfmt
https://github.com/rust-lang/rustfmt/issues/3666#issuecomment-714612257
update references after formatting
fix dogfood issues
fix multi-cursor edit
fix missed dogfood error
fix more dogfood pedantic issues, including function length
even more nesting
insert hidden definition of Vec3 so docs compile
add spaces to second struct def
reword test description comment
Co-authored-by: llogiq <bogusandre@gmail.com>
add local `use BinOpKind::*;`
Apply suggestions from code review
Co-authored-by: llogiq <bogusandre@gmail.com>
switch `SUSPICIOUS_OPERATION_GROUPINGS` to a style lint
run `cargo dev update_lints`
put both usages of `op_types` in the same closure to satisfy `borrowck`
fix compile error
2020-11-07 23:00:42 +00:00
|
|
|
}
|
2022-02-08 16:45:52 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn eq_op_shouldnt_trigger_in_tests() {
|
|
|
|
let a = 1;
|
|
|
|
let result = a + 1 == 1 + a;
|
|
|
|
assert!(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn eq_op_macros_shouldnt_trigger_in_tests() {
|
|
|
|
let a = 1;
|
|
|
|
let b = 2;
|
|
|
|
assert_eq!(a, a);
|
|
|
|
assert_eq!(a + b, b + a);
|
|
|
|
}
|