Skip to content

Commit ca5d48a

Browse files
committed
avoid eq_op in test code
1 parent 5c97b27 commit ca5d48a

File tree

3 files changed

+46
-18
lines changed

3 files changed

+46
-18
lines changed

clippy_lints/src/eq_op.rs

+31-18
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ use clippy_utils::ty::{implements_trait, is_copy};
44
use clippy_utils::{ast_utils::is_useless_with_eq_exprs, eq_expr_value, higher, in_macro, is_expn_of};
55
use if_chain::if_chain;
66
use rustc_errors::Applicability;
7-
use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, StmtKind};
7+
use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, HirId, StmtKind};
88
use rustc_lint::{LateContext, LateLintPass};
99
use rustc_session::{declare_lint_pass, declare_tool_lint};
10+
use rustc_span::sym;
1011

1112
declare_clippy_lint! {
1213
/// ### What it does
@@ -68,27 +69,36 @@ declare_lint_pass!(EqOp => [EQ_OP, OP_REF]);
6869

6970
const ASSERT_MACRO_NAMES: [&str; 4] = ["assert_eq", "assert_ne", "debug_assert_eq", "debug_assert_ne"];
7071

72+
fn in_test_function(cx: &LateContext<'_>, elem_id: HirId) -> bool {
73+
if let Some(def_id) = cx.tcx.hir().opt_local_def_id(cx.tcx.hir().get_parent_item(elem_id)) {
74+
return cx.tcx.has_attr(def_id.to_def_id(), sym::test);
75+
}
76+
false
77+
}
78+
7179
impl<'tcx> LateLintPass<'tcx> for EqOp {
7280
#[allow(clippy::similar_names, clippy::too_many_lines)]
7381
fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
7482
if let ExprKind::Block(block, _) = e.kind {
75-
for stmt in block.stmts {
76-
for amn in &ASSERT_MACRO_NAMES {
77-
if_chain! {
78-
if is_expn_of(stmt.span, amn).is_some();
79-
if let StmtKind::Semi(matchexpr) = stmt.kind;
80-
if let Some(macro_args) = higher::extract_assert_macro_args(matchexpr);
81-
if macro_args.len() == 2;
82-
let (lhs, rhs) = (macro_args[0], macro_args[1]);
83-
if eq_expr_value(cx, lhs, rhs);
83+
if !in_test_function(cx, e.hir_id) {
84+
for stmt in block.stmts {
85+
for amn in &ASSERT_MACRO_NAMES {
86+
if_chain! {
87+
if is_expn_of(stmt.span, amn).is_some();
88+
if let StmtKind::Semi(matchexpr) = stmt.kind;
89+
if let Some(macro_args) = higher::extract_assert_macro_args(matchexpr);
90+
if macro_args.len() == 2;
91+
let (lhs, rhs) = (macro_args[0], macro_args[1]);
92+
if eq_expr_value(cx, lhs, rhs);
8493

85-
then {
86-
span_lint(
87-
cx,
88-
EQ_OP,
89-
lhs.span.to(rhs.span),
90-
&format!("identical args used in this `{}!` macro call", amn),
91-
);
94+
then {
95+
span_lint(
96+
cx,
97+
EQ_OP,
98+
lhs.span.to(rhs.span),
99+
&format!("identical args used in this `{}!` macro call", amn),
100+
);
101+
}
92102
}
93103
}
94104
}
@@ -108,7 +118,10 @@ impl<'tcx> LateLintPass<'tcx> for EqOp {
108118
if macro_with_not_op(&left.kind) || macro_with_not_op(&right.kind) {
109119
return;
110120
}
111-
if is_useless_with_eq_exprs(op.node.into()) && eq_expr_value(cx, left, right) {
121+
if is_useless_with_eq_exprs(op.node.into())
122+
&& !in_test_function(cx, e.hir_id)
123+
&& eq_expr_value(cx, left, right)
124+
{
112125
span_lint(
113126
cx,
114127
EQ_OP,

tests/ui/eq_op.rs

+7
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,10 @@ fn check_nested(n1: &Nested, n2: &Nested) -> bool {
9595
// `n2.inner.0.0` mistyped as `n1.inner.0.0`
9696
(n1.inner.0).0 == (n1.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.2).0
9797
}
98+
99+
#[test]
100+
fn eq_op_shouldnt_trigger_in_tests() {
101+
let a = 1;
102+
let result = a + 1 == 1 + a;
103+
assert!(result);
104+
}

tests/ui/eq_op_macros.rs

+8
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,11 @@ fn main() {
5454
let mut my_iter = my_vec.iter();
5555
assert_ne!(my_iter.next(), my_iter.next());
5656
}
57+
58+
#[test]
59+
fn eq_op_shouldnt_trigger_in_tests() {
60+
let a = 1;
61+
let b = 2;
62+
assert_eq!(a, a);
63+
assert_eq!(a + b, b + a);
64+
}

0 commit comments

Comments
 (0)