From 437cc536d2d460be2d3cf72b8bf93d75d34e4644 Mon Sep 17 00:00:00 2001 From: tx-tomcat Date: Wed, 6 Nov 2024 11:25:31 +0700 Subject: [PATCH] refactor and add testcase --- .../crates/move-compiler/src/linters/eq_op.rs | 82 ++++---------- .../crates/move-compiler/src/linters/mod.rs | 9 +- .../linter/false_negative_equal_operand.exp | 38 +++++++ .../linter/false_negative_equal_operand.move | 24 ++++ ...se_negative_meaningless_math_operation.exp | 8 ++ .../false_negative_unnecessary_while_loop.exp | 8 ++ .../linter/false_positive_equal_operand.exp | 78 +++++++++++++ .../linter/false_positive_equal_operand.move | 35 ++++++ .../tests/linter/incorrect_eq_op.exp | 72 ------------ .../tests/linter/incorrect_eq_op.move | 22 ---- .../tests/linter/suppress_equal_operand.move | 16 +++ .../linter/true_negative_equal_operand.move | 26 +++++ .../true_negative_unnecessary_while_loop.exp | 8 ++ .../linter/true_positive_equal_operand.exp | 104 ++++++++++++++++++ .../linter/true_positive_equal_operand.move | 26 +++++ ...ue_positive_meaningless_math_operation.exp | 8 ++ 16 files changed, 408 insertions(+), 156 deletions(-) create mode 100644 external-crates/move/crates/move-compiler/tests/linter/false_negative_equal_operand.exp create mode 100644 external-crates/move/crates/move-compiler/tests/linter/false_negative_equal_operand.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/false_negative_meaningless_math_operation.exp create mode 100644 external-crates/move/crates/move-compiler/tests/linter/false_negative_unnecessary_while_loop.exp create mode 100644 external-crates/move/crates/move-compiler/tests/linter/false_positive_equal_operand.exp create mode 100644 external-crates/move/crates/move-compiler/tests/linter/false_positive_equal_operand.move delete mode 100644 external-crates/move/crates/move-compiler/tests/linter/incorrect_eq_op.exp delete mode 100644 external-crates/move/crates/move-compiler/tests/linter/incorrect_eq_op.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/suppress_equal_operand.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/true_negative_equal_operand.move create mode 100644 external-crates/move/crates/move-compiler/tests/linter/true_negative_unnecessary_while_loop.exp create mode 100644 external-crates/move/crates/move-compiler/tests/linter/true_positive_equal_operand.exp create mode 100644 external-crates/move/crates/move-compiler/tests/linter/true_positive_equal_operand.move diff --git a/external-crates/move/crates/move-compiler/src/linters/eq_op.rs b/external-crates/move/crates/move-compiler/src/linters/eq_op.rs index 7872ccdbfa6e4..81f6077807cd1 100644 --- a/external-crates/move/crates/move-compiler/src/linters/eq_op.rs +++ b/external-crates/move/crates/move-compiler/src/linters/eq_op.rs @@ -3,84 +3,44 @@ //! Implements a lint to detect and warn about binary operations with equal operands in Move code. //! Targets comparison, logical, bitwise, subtraction, and division operations where such usage might indicate errors or redundancies. + +use super::StyleCodes; +use crate::parser::ast::BinOp_; use crate::{ diag, - diagnostics::{ - codes::{custom, DiagnosticInfo, Severity}, - WarningFilters, - }, - parser::ast::BinOp_, - shared::CompilationEnv, typing::{ ast::{self as T, UnannotatedExp_}, - visitor::{TypingVisitorConstructor, TypingVisitorContext}, + visitor::simple_visitor, }, }; -use move_ir_types::location::Loc; - -use super::{LinterDiagnosticCategory, EQUAL_OPERANDS_DIAG_CODE, LINT_WARNING_PREFIX}; - -const EQUAL_OPERANDS_DIAG: DiagnosticInfo = custom( - LINT_WARNING_PREFIX, - Severity::Warning, - LinterDiagnosticCategory::Suspicious as u8, - EQUAL_OPERANDS_DIAG_CODE, - "Equal operands detected in binary operation, which might indicate a logical error or redundancy.", -); - -pub struct EqualOperandsCheck; - -pub struct Context<'a> { - env: &'a mut CompilationEnv, -} - -impl TypingVisitorConstructor for EqualOperandsCheck { - type Context<'a> = Context<'a>; - fn context<'a>(env: &'a mut CompilationEnv, _program: &T::Program) -> Self::Context<'a> { - Context { env } - } -} - -impl TypingVisitorContext for Context<'_> { - fn visit_exp_custom(&mut self, exp: &mut T::Exp) -> bool { +simple_visitor!( + EqualOperandsCheck, + fn visit_exp_custom(&mut self, exp: &T::Exp) -> bool { if let UnannotatedExp_::BinopExp(lhs, sp!(_, op), _, rhs) = &exp.exp.value { - if lhs.exp.value == rhs.exp.value && is_relevant_op(op) { - report_equal_operands(self.env, exp.exp.loc); + if should_check_operands(lhs, rhs, op) { + let diag = diag!( + StyleCodes::EqualOperands.diag_info(), + ( + exp.exp.loc, + "Equal operands detected in binary operation, which might indicate a logical error or redundancy." + ) + ); + self.add_diag(diag); } } false } - fn add_warning_filter_scope(&mut self, filter: WarningFilters) { - self.env.add_warning_filter_scope(filter) - } +); - fn pop_warning_filter_scope(&mut self) { - self.env.pop_warning_filter_scope() - } +fn should_check_operands(lhs: &T::Exp, rhs: &T::Exp, op: &BinOp_) -> bool { + lhs.exp.value == rhs.exp.value && is_relevant_op(op) } fn is_relevant_op(op: &BinOp_) -> bool { + use BinOp_::*; matches!( op, - BinOp_::Eq - | BinOp_::Neq - | BinOp_::Gt - | BinOp_::Ge - | BinOp_::Lt - | BinOp_::Le - | BinOp_::And - | BinOp_::Or - | BinOp_::BitAnd - | BinOp_::BitOr - | BinOp_::Xor - | BinOp_::Sub - | BinOp_::Div + Eq | Neq | Gt | Ge | Lt | Le | And | Or | BitAnd | BitOr | Xor | Sub | Div ) } - -fn report_equal_operands(env: &mut CompilationEnv, loc: Loc) { - let msg = "Equal operands detected in binary operation, which might indicate a logical error or redundancy."; - let diag = diag!(EQUAL_OPERANDS_DIAG, (loc, msg)); - env.add_diag(diag); -} diff --git a/external-crates/move/crates/move-compiler/src/linters/mod.rs b/external-crates/move/crates/move-compiler/src/linters/mod.rs index 6f02e2e2cd4a9..328be1a79ba52 100644 --- a/external-crates/move/crates/move-compiler/src/linters/mod.rs +++ b/external-crates/move/crates/move-compiler/src/linters/mod.rs @@ -15,6 +15,7 @@ use crate::{ pub mod abort_constant; pub mod constant_naming; +pub mod eq_op; pub mod loop_without_exit; pub mod meaningless_math_operation; pub mod redundant_ref_deref; @@ -23,7 +24,6 @@ pub mod unnecessary_conditional; pub mod unnecessary_unit; pub mod unnecessary_while_loop; pub mod unneeded_return; - #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum LintLevel { // No linters @@ -162,6 +162,12 @@ lints!( "unnecessary_unit", "unit `()` expression can be removed or simplified" ), + ( + EqualOperands, + LinterDiagnosticCategory::Suspicious, + "equal_operands", + "Equal operands detected in binary operation, which might indicate a logical error or redundancy." + ), ); pub const ALLOW_ATTR_CATEGORY: &str = "lint"; @@ -199,6 +205,7 @@ pub fn linter_visitors(level: LintLevel) -> Vec { self_assignment::SelfAssignmentVisitor.visitor(), redundant_ref_deref::RedundantRefDerefVisitor.visitor(), unnecessary_unit::UnnecessaryUnit.visitor(), + eq_op::EqualOperandsCheck.visitor(), ] } } diff --git a/external-crates/move/crates/move-compiler/tests/linter/false_negative_equal_operand.exp b/external-crates/move/crates/move-compiler/tests/linter/false_negative_equal_operand.exp new file mode 100644 index 0000000000000..3d0a2f74d14e0 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/false_negative_equal_operand.exp @@ -0,0 +1,38 @@ +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/false_negative_equal_operand.move:5:18 + │ +5 │ let _ = (x + 0) == x; // Semantically same operands but syntactically different + │ ^^^^^ + │ │ │ + │ │ Because of this operand + │ This operation has no effect and can be removed + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W01003]: math operator can be simplified + ┌─ tests/linter/false_negative_equal_operand.move:6:18 + │ +6 │ let _ = (x * 1) == x; // Semantically same operands but syntactically different + │ ^^^^^ + │ │ │ + │ │ Because of this operand + │ This operation has no effect and can be removed + │ + = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02011]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. + ┌─ tests/linter/false_negative_equal_operand.move:9:17 + │ +9 │ let _ = get_constant() == get_constant(); // Same value but lint won't catch it + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. + │ + = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02011]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. + ┌─ tests/linter/false_negative_equal_operand.move:19:17 + │ +19 │ let _ = s == s; // Should trigger lint + │ ^^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. + │ + = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/linter/false_negative_equal_operand.move b/external-crates/move/crates/move-compiler/tests/linter/false_negative_equal_operand.move new file mode 100644 index 0000000000000..a1efee8c0bed7 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/false_negative_equal_operand.move @@ -0,0 +1,24 @@ +module 0x42::false_negative_equal_operand { + fun test_false_negatives() { + // Complex expressions that are effectively the same but syntactically different + let x = 10; + let _ = (x + 0) == x; // Semantically same operands but syntactically different + let _ = (x * 1) == x; // Semantically same operands but syntactically different + + // Function calls that return the same value + let _ = get_constant() == get_constant(); // Same value but lint won't catch it + } + + fun get_constant(): u64 { 42 } + + // Additional test for struct equality + struct TestStruct has copy, drop { value: u64 } + + fun test_struct_operations() { + let s = TestStruct { value: 10 }; + let _ = s == s; // Should trigger lint + + let s2 = TestStruct { value: 10 }; + let _ = s == s2; // Should not trigger lint (different instances) + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/false_negative_meaningless_math_operation.exp b/external-crates/move/crates/move-compiler/tests/linter/false_negative_meaningless_math_operation.exp new file mode 100644 index 0000000000000..8bd20f25278e1 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/false_negative_meaningless_math_operation.exp @@ -0,0 +1,8 @@ +warning[Lint W02011]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. + ┌─ tests/linter/false_negative_meaningless_math_operation.move:3:14 + │ +3 │ x * (y - y) // This is effectively * 0, but is not currently caught + │ ^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. + │ + = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/linter/false_negative_unnecessary_while_loop.exp b/external-crates/move/crates/move-compiler/tests/linter/false_negative_unnecessary_while_loop.exp new file mode 100644 index 0000000000000..1e0634ac041e3 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/false_negative_unnecessary_while_loop.exp @@ -0,0 +1,8 @@ +warning[Lint W02011]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. + ┌─ tests/linter/false_negative_unnecessary_while_loop.move:7:16 + │ +7 │ while (true && true) {}; + │ ^^^^^^^^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. + │ + = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/linter/false_positive_equal_operand.exp b/external-crates/move/crates/move-compiler/tests/linter/false_positive_equal_operand.exp new file mode 100644 index 0000000000000..8e214c15b0017 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/false_positive_equal_operand.exp @@ -0,0 +1,78 @@ +warning[W09002]: unused variable + ┌─ tests/linter/false_positive_equal_operand.move:4:13 + │ +4 │ let mut_ref = &mut 0; + │ ^^^^^^^ Unused local variable 'mut_ref'. Consider removing or prefixing with an underscore: '_mut_ref' + │ + = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +error[E01002]: unexpected token + ┌─ tests/linter/false_positive_equal_operand.move:5:15 + │ +5 │ while *mut_ref != *mut_ref { // Legitimate use: checking for changes in mutable reference + │ ^ + │ │ + │ Unexpected '*' + │ Expected '(' + +warning[W09002]: unused variable + ┌─ tests/linter/false_positive_equal_operand.move:10:13 + │ +10 │ let nan_check = is_nan(1.0); // Simulated floating point check + │ ^^^^^^^^^ Unused local variable 'nan_check'. Consider removing or prefixing with an underscore: '_nan_check' + │ + = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +error[E01002]: unexpected token + ┌─ tests/linter/false_positive_equal_operand.move:10:34 + │ +10 │ let nan_check = is_nan(1.0); // Simulated floating point check + │ ^ + │ │ + │ Unexpected '0' + │ Expected an identifier or a decimal number + +error[E13001]: feature is not supported in specified edition + ┌─ tests/linter/false_positive_equal_operand.move:10:34 + │ +10 │ let nan_check = is_nan(1.0); // Simulated floating point check + │ ^ Positional fields are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ + = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. + +warning[Lint W02011]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. + ┌─ tests/linter/false_positive_equal_operand.move:19:17 + │ +19 │ assert!(x <= x && x <= y, 0); // Legitimate use in monotonicity checks + │ ^^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. + │ + = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +error[E04007]: incompatible types + ┌─ tests/linter/false_positive_equal_operand.move:33:9 + │ +31 │ fun reference_equals(a: &T, b: &T): bool { + │ -- Given: '&T' +32 │ // Simulated reference equality check +33 │ std::hash::sha2_256(a) == std::hash::sha2_256(b) + │ ^^^^^^^^^^^^^^^^^^^^^^ Invalid call of 'std::hash::sha2_256'. Invalid argument for parameter 'data' + │ + ┌─ /Users/dmr/Projects/rust/sui-network/external-crates/move/crates/move-stdlib/sources/hash.move:9:38 + │ + 9 │ native public fun sha2_256(data: vector): vector; + │ ---------- Expected: 'vector' + +error[E04007]: incompatible types + ┌─ tests/linter/false_positive_equal_operand.move:33:35 + │ +31 │ fun reference_equals(a: &T, b: &T): bool { + │ -- Given: '&T' +32 │ // Simulated reference equality check +33 │ std::hash::sha2_256(a) == std::hash::sha2_256(b) + │ ^^^^^^^^^^^^^^^^^^^^^^ Invalid call of 'std::hash::sha2_256'. Invalid argument for parameter 'data' + │ + ┌─ /Users/dmr/Projects/rust/sui-network/external-crates/move/crates/move-stdlib/sources/hash.move:9:38 + │ + 9 │ native public fun sha2_256(data: vector): vector; + │ ---------- Expected: 'vector' + diff --git a/external-crates/move/crates/move-compiler/tests/linter/false_positive_equal_operand.move b/external-crates/move/crates/move-compiler/tests/linter/false_positive_equal_operand.move new file mode 100644 index 0000000000000..c42039297e37c --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/false_positive_equal_operand.move @@ -0,0 +1,35 @@ +module 0x42::false_positive_equal_operand { + fun test_false_positives() { + // Iterator-like patterns where comparing same variable is intentional + let mut_ref = &mut 0; + while *mut_ref != *mut_ref { // Legitimate use: checking for changes in mutable reference + break + }; + + // Checking for NaN (Not a Number) in floating point implementations + let nan_check = is_nan(1.0); // Simulated floating point check + + // Checking for pointer/reference equality (if Move had raw pointers) + let obj = object(); + let _ = reference_equals(obj, obj); // Legitimate use: checking if references point to same object + + // Checking for monotonicity + let x = 10; + let y = 20; + assert!(x <= x && x <= y, 0); // Legitimate use in monotonicity checks + } + + // Helper functions for false positive cases + fun is_nan(_x: u64): bool { + false // Simulated NaN check + } + + fun object(): &vector { + &vector[1, 2, 3] + } + + fun reference_equals(a: &T, b: &T): bool { + // Simulated reference equality check + std::hash::sha2_256(a) == std::hash::sha2_256(b) + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/incorrect_eq_op.exp b/external-crates/move/crates/move-compiler/tests/linter/incorrect_eq_op.exp deleted file mode 100644 index ce795dcf1367b..0000000000000 --- a/external-crates/move/crates/move-compiler/tests/linter/incorrect_eq_op.exp +++ /dev/null @@ -1,72 +0,0 @@ -warning[Lint W02009]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. - ┌─ tests/linter/incorrect_eq_op.move:8:17 - │ -8 │ let _ = a == a; - │ ^^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. - │ - = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') - -warning[Lint W02009]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. - ┌─ tests/linter/incorrect_eq_op.move:9:17 - │ -9 │ let _ = b != b; - │ ^^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. - │ - = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') - -warning[Lint W02009]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. - ┌─ tests/linter/incorrect_eq_op.move:10:17 - │ -10 │ let _ = a > a; - │ ^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. - │ - = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') - -warning[Lint W02009]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. - ┌─ tests/linter/incorrect_eq_op.move:11:17 - │ -11 │ let _ = a >= a; - │ ^^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. - │ - = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') - -warning[Lint W02009]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. - ┌─ tests/linter/incorrect_eq_op.move:14:17 - │ -14 │ let _ = a & a; - │ ^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. - │ - = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') - -warning[Lint W02009]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. - ┌─ tests/linter/incorrect_eq_op.move:15:17 - │ -15 │ let _ = b | b; - │ ^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. - │ - = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') - -warning[Lint W02009]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. - ┌─ tests/linter/incorrect_eq_op.move:16:17 - │ -16 │ let _ = a ^ a; - │ ^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. - │ - = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') - -warning[Lint W02009]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. - ┌─ tests/linter/incorrect_eq_op.move:19:17 - │ -19 │ let _ = a - a; - │ ^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. - │ - = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') - -warning[Lint W02009]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. - ┌─ tests/linter/incorrect_eq_op.move:20:17 - │ -20 │ let _ = b / b; - │ ^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. - │ - = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') - diff --git a/external-crates/move/crates/move-compiler/tests/linter/incorrect_eq_op.move b/external-crates/move/crates/move-compiler/tests/linter/incorrect_eq_op.move deleted file mode 100644 index 2f02c4bc6d763..0000000000000 --- a/external-crates/move/crates/move-compiler/tests/linter/incorrect_eq_op.move +++ /dev/null @@ -1,22 +0,0 @@ -module 0x42::M { - - fun func1() { - let a = 5; - let b = 10; - - // Comparison operations with equal operands (should trigger lint) - let _ = a == a; - let _ = b != b; - let _ = a > a; - let _ = a >= a; - - // Bitwise operations with equal operands (should trigger lint) - let _ = a & a; - let _ = b | b; - let _ = a ^ a; - - // Difference and division operations with equal operands (should trigger lint) - let _ = a - a; - let _ = b / b; - } -} diff --git a/external-crates/move/crates/move-compiler/tests/linter/suppress_equal_operand.move b/external-crates/move/crates/move-compiler/tests/linter/suppress_equal_operand.move new file mode 100644 index 0000000000000..3a2ad38e2a6fd --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/suppress_equal_operand.move @@ -0,0 +1,16 @@ +module 0x42::suppress_equal_operand { + // Example of suppressing at module level + #[allow(lint(equal_operands))] + fun suppressed_function() { + let x = 10; + let _ = x == x; // Lint suppressed for entire function + } + + // Example of conditional suppression based on configuration + #[allow(lint(equal_operands))] + fun conditionally_suppressed() { + let x = 10; + let _ = x == x; // Lint suppressed only when "testing" feature is enabled + } + +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_negative_equal_operand.move b/external-crates/move/crates/move-compiler/tests/linter/true_negative_equal_operand.move new file mode 100644 index 0000000000000..c0d8a28898c99 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/true_negative_equal_operand.move @@ -0,0 +1,26 @@ +module 0x42::true_negative_equal_operand { + fun test_equal_operands_comparison() { + let x = 10; + let y = 20; + + // Different operands + let _ = x == y; + let _ = x != y; + let _ = x > y; + let _ = x >= y; + let _ = x < y; + let _ = x <= y; + + // Valid arithmetic operations + let _ = x + y; // Addition is not checked + let _ = x * y; // Multiplication is not checked + let _ = x % y; // Modulo is not checked + + // Different values + let _ = true && false; + let _ = false || true; + let _ = 5 & 3; + let _ = 5 | 3; + let _ = 5 ^ 3; + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_negative_unnecessary_while_loop.exp b/external-crates/move/crates/move-compiler/tests/linter/true_negative_unnecessary_while_loop.exp new file mode 100644 index 0000000000000..a71c1c76af3f0 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/true_negative_unnecessary_while_loop.exp @@ -0,0 +1,8 @@ +warning[Lint W02011]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. + ┌─ tests/linter/true_negative_unnecessary_while_loop.move:8:16 + │ +8 │ while (false || false) {}; + │ ^^^^^^^^^^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. + │ + = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_positive_equal_operand.exp b/external-crates/move/crates/move-compiler/tests/linter/true_positive_equal_operand.exp new file mode 100644 index 0000000000000..f0d3e9b829e84 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/true_positive_equal_operand.exp @@ -0,0 +1,104 @@ +warning[Lint W02011]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. + ┌─ tests/linter/true_positive_equal_operand.move:6:17 + │ +6 │ let _ = x == x; // lint warning expected + │ ^^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. + │ + = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02011]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. + ┌─ tests/linter/true_positive_equal_operand.move:7:17 + │ +7 │ let _ = x != x; // lint warning expected + │ ^^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. + │ + = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02011]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. + ┌─ tests/linter/true_positive_equal_operand.move:8:17 + │ +8 │ let _ = x > x; // lint warning expected + │ ^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. + │ + = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02011]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. + ┌─ tests/linter/true_positive_equal_operand.move:9:17 + │ +9 │ let _ = x >= x; // lint warning expected + │ ^^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. + │ + = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02011]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. + ┌─ tests/linter/true_positive_equal_operand.move:10:17 + │ +10 │ let _ = x < x; // lint warning expected + │ ^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. + │ + = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02011]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. + ┌─ tests/linter/true_positive_equal_operand.move:11:17 + │ +11 │ let _ = x <= x; // lint warning expected + │ ^^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. + │ + = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02011]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. + ┌─ tests/linter/true_positive_equal_operand.move:14:17 + │ +14 │ let _ = true && true; // lint warning expected + │ ^^^^^^^^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. + │ + = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02011]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. + ┌─ tests/linter/true_positive_equal_operand.move:15:17 + │ +15 │ let _ = false || false; // lint warning expected + │ ^^^^^^^^^^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. + │ + = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02011]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. + ┌─ tests/linter/true_positive_equal_operand.move:18:17 + │ +18 │ let _ = x & x; // lint warning expected + │ ^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. + │ + = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02011]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. + ┌─ tests/linter/true_positive_equal_operand.move:19:17 + │ +19 │ let _ = x | x; // lint warning expected + │ ^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. + │ + = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02011]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. + ┌─ tests/linter/true_positive_equal_operand.move:20:17 + │ +20 │ let _ = x ^ x; // lint warning expected + │ ^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. + │ + = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02011]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. + ┌─ tests/linter/true_positive_equal_operand.move:23:17 + │ +23 │ let _ = x - x; // lint warning expected + │ ^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. + │ + = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +warning[Lint W02011]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. + ┌─ tests/linter/true_positive_equal_operand.move:24:17 + │ +24 │ let _ = x / x; // lint warning expected + │ ^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. + │ + = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_positive_equal_operand.move b/external-crates/move/crates/move-compiler/tests/linter/true_positive_equal_operand.move new file mode 100644 index 0000000000000..12507f9a5f1e1 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/linter/true_positive_equal_operand.move @@ -0,0 +1,26 @@ +module 0x42::true_positive_equal_operand { + fun test_equal_operands_comparison() { + let x = 10; + + // Comparison operators + let _ = x == x; // lint warning expected + let _ = x != x; // lint warning expected + let _ = x > x; // lint warning expected + let _ = x >= x; // lint warning expected + let _ = x < x; // lint warning expected + let _ = x <= x; // lint warning expected + + // Logical operators + let _ = true && true; // lint warning expected + let _ = false || false; // lint warning expected + + // Bitwise operators + let _ = x & x; // lint warning expected + let _ = x | x; // lint warning expected + let _ = x ^ x; // lint warning expected + + // Arithmetic operators + let _ = x - x; // lint warning expected + let _ = x / x; // lint warning expected + } +} diff --git a/external-crates/move/crates/move-compiler/tests/linter/true_positive_meaningless_math_operation.exp b/external-crates/move/crates/move-compiler/tests/linter/true_positive_meaningless_math_operation.exp index 2f96dcd1e65ad..7c8c63d799f62 100644 --- a/external-crates/move/crates/move-compiler/tests/linter/true_positive_meaningless_math_operation.exp +++ b/external-crates/move/crates/move-compiler/tests/linter/true_positive_meaningless_math_operation.exp @@ -173,6 +173,14 @@ warning[Lint W01003]: math operator can be simplified │ = This warning can be suppressed with '#[allow(lint(unnecessary_math))]' applied to the 'module' or module member ('const', 'fun', or 'struct') +warning[Lint W02011]: Equal operands detected in binary operation, which might indicate a logical error or redundancy. + ┌─ tests/linter/true_positive_meaningless_math_operation.move:28:14 + │ +28 │ x - (1 - 1); + │ ^^^^^ Equal operands detected in binary operation, which might indicate a logical error or redundancy. + │ + = This warning can be suppressed with '#[allow(lint(equal_operands))]' applied to the 'module' or module member ('const', 'fun', or 'struct') + warning[Lint W01003]: math operator can be simplified ┌─ tests/linter/true_positive_meaningless_math_operation.move:32:9 │