@@ -4,9 +4,10 @@ use clippy_utils::ty::{implements_trait, is_copy};
4
4
use clippy_utils:: { ast_utils:: is_useless_with_eq_exprs, eq_expr_value, higher, in_macro, is_expn_of} ;
5
5
use if_chain:: if_chain;
6
6
use rustc_errors:: Applicability ;
7
- use rustc_hir:: { BinOpKind , BorrowKind , Expr , ExprKind , StmtKind } ;
7
+ use rustc_hir:: { BinOpKind , BorrowKind , Expr , ExprKind , HirId , StmtKind } ;
8
8
use rustc_lint:: { LateContext , LateLintPass } ;
9
9
use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
10
+ use rustc_span:: sym;
10
11
11
12
declare_clippy_lint ! {
12
13
/// ### What it does
@@ -68,27 +69,36 @@ declare_lint_pass!(EqOp => [EQ_OP, OP_REF]);
68
69
69
70
const ASSERT_MACRO_NAMES : [ & str ; 4 ] = [ "assert_eq" , "assert_ne" , "debug_assert_eq" , "debug_assert_ne" ] ;
70
71
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
+
71
79
impl < ' tcx > LateLintPass < ' tcx > for EqOp {
72
80
#[ allow( clippy:: similar_names, clippy:: too_many_lines) ]
73
81
fn check_expr ( & mut self , cx : & LateContext < ' tcx > , e : & ' tcx Expr < ' _ > ) {
74
82
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) ;
84
93
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
+ }
92
102
}
93
103
}
94
104
}
@@ -108,7 +118,10 @@ impl<'tcx> LateLintPass<'tcx> for EqOp {
108
118
if macro_with_not_op ( & left. kind ) || macro_with_not_op ( & right. kind ) {
109
119
return ;
110
120
}
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
+ {
112
125
span_lint (
113
126
cx,
114
127
EQ_OP ,
0 commit comments