@@ -3,7 +3,7 @@ use crate::utils::paths;
3
3
use crate :: utils:: sugg:: Sugg ;
4
4
use if_chain:: if_chain;
5
5
use rustc_errors:: Applicability ;
6
- use rustc_hir:: * ;
6
+ use rustc_hir:: { Expr , ExprKind , Mutability , Param , Pat , PatKind , Path , QPath } ;
7
7
use rustc_lint:: { LateContext , LateLintPass } ;
8
8
use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
9
9
use rustc_span:: symbol:: Ident ;
@@ -43,64 +43,105 @@ struct LintTrigger {
43
43
44
44
/// Detect if the two expressions are mirrored (identical, except one
45
45
/// contains a and the other replaces it with b)
46
- fn mirrored_exprs ( cx : & LateContext < ' _ , ' _ > , a_expr : & Expr < ' _ > , a_ident : & Ident , b_expr : & Expr < ' _ > , b_ident : & Ident ) -> bool {
46
+ fn mirrored_exprs (
47
+ cx : & LateContext < ' _ , ' _ > ,
48
+ a_expr : & Expr < ' _ > ,
49
+ a_ident : & Ident ,
50
+ b_expr : & Expr < ' _ > ,
51
+ b_ident : & Ident ,
52
+ ) -> bool {
47
53
match ( & a_expr. kind , & b_expr. kind ) {
48
54
// Two boxes with mirrored contents
49
- ( ExprKind :: Box ( left_expr) , ExprKind :: Box ( right_expr) ) => mirrored_exprs ( cx, left_expr, a_ident, right_expr, b_ident) ,
55
+ ( ExprKind :: Box ( left_expr) , ExprKind :: Box ( right_expr) ) => {
56
+ mirrored_exprs ( cx, left_expr, a_ident, right_expr, b_ident)
57
+ } ,
50
58
// Two arrays with mirrored contents
51
- ( ExprKind :: Array ( left_exprs) , ExprKind :: Array ( right_exprs) )
52
- => left_exprs. iter ( ) . zip ( right_exprs. iter ( ) ) . all ( |( left, right) | mirrored_exprs ( cx, left, a_ident, right, b_ident) ) ,
59
+ ( ExprKind :: Array ( left_exprs) , ExprKind :: Array ( right_exprs) ) => left_exprs
60
+ . iter ( )
61
+ . zip ( right_exprs. iter ( ) )
62
+ . all ( |( left, right) | mirrored_exprs ( cx, left, a_ident, right, b_ident) ) ,
53
63
// The two exprs are function calls.
54
64
// Check to see that the function itself and its arguments are mirrored
55
- ( ExprKind :: Call ( left_expr, left_args) , ExprKind :: Call ( right_expr, right_args) )
56
- => {
57
- // println!("{:?}\n{:?}\n", left_expr, left_args);
58
- // println!("{:?}\n{:?}\n", right_expr, right_args);
59
- mirrored_exprs ( cx , left_expr , a_ident , right_expr , b_ident )
60
- && left_args . iter ( ) . zip ( right_args . iter ( ) ) . all ( |( left, right) | mirrored_exprs ( cx, left, a_ident, right, b_ident) )
61
- } ,
65
+ ( ExprKind :: Call ( left_expr, left_args) , ExprKind :: Call ( right_expr, right_args) ) => {
66
+ mirrored_exprs ( cx , left_expr , a_ident , right_expr , b_ident )
67
+ && left_args
68
+ . iter ( )
69
+ . zip ( right_args . iter ( ) )
70
+ . all ( |( left, right) | mirrored_exprs ( cx, left, a_ident, right, b_ident) )
71
+ } ,
62
72
// The two exprs are method calls.
63
73
// Check to see that the function is the same and the arguments are mirrored
64
74
// This is enough because the receiver of the method is listed in the arguments
65
- ( ExprKind :: MethodCall ( left_segment, _, left_args) , ExprKind :: MethodCall ( right_segment, _, right_args) )
66
- => left_segment. ident == right_segment. ident
67
- && left_args. iter ( ) . zip ( right_args. iter ( ) ) . all ( |( left, right) | mirrored_exprs ( cx, left, a_ident, right, b_ident) ) ,
75
+ ( ExprKind :: MethodCall ( left_segment, _, left_args) , ExprKind :: MethodCall ( right_segment, _, right_args) ) => {
76
+ left_segment. ident == right_segment. ident
77
+ && left_args
78
+ . iter ( )
79
+ . zip ( right_args. iter ( ) )
80
+ . all ( |( left, right) | mirrored_exprs ( cx, left, a_ident, right, b_ident) )
81
+ } ,
68
82
// Two tuples with mirrored contents
69
- ( ExprKind :: Tup ( left_exprs) , ExprKind :: Tup ( right_exprs) )
70
- => left_exprs. iter ( ) . zip ( right_exprs. iter ( ) ) . all ( |( left, right) | mirrored_exprs ( cx, left, a_ident, right, b_ident) ) ,
83
+ ( ExprKind :: Tup ( left_exprs) , ExprKind :: Tup ( right_exprs) ) => left_exprs
84
+ . iter ( )
85
+ . zip ( right_exprs. iter ( ) )
86
+ . all ( |( left, right) | mirrored_exprs ( cx, left, a_ident, right, b_ident) ) ,
71
87
// Two binary ops, which are the same operation and which have mirrored arguments
72
- ( ExprKind :: Binary ( left_op, left_left, left_right) , ExprKind :: Binary ( right_op, right_left, right_right) )
73
- => left_op. node == right_op. node
88
+ ( ExprKind :: Binary ( left_op, left_left, left_right) , ExprKind :: Binary ( right_op, right_left, right_right) ) => {
89
+ left_op. node == right_op. node
74
90
&& mirrored_exprs ( cx, left_left, a_ident, right_left, b_ident)
75
- && mirrored_exprs ( cx, left_right, a_ident, right_right, b_ident) ,
91
+ && mirrored_exprs ( cx, left_right, a_ident, right_right, b_ident)
92
+ } ,
76
93
// Two unary ops, which are the same operation and which have the same argument
77
- ( ExprKind :: Unary ( left_op, left_expr) , ExprKind :: Unary ( right_op, right_expr) )
78
- => left_op == right_op && mirrored_exprs ( cx, left_expr, a_ident, right_expr, b_ident) ,
94
+ ( ExprKind :: Unary ( left_op, left_expr) , ExprKind :: Unary ( right_op, right_expr) ) => {
95
+ left_op == right_op && mirrored_exprs ( cx, left_expr, a_ident, right_expr, b_ident)
96
+ } ,
79
97
// The two exprs are literals of some kind
80
98
( ExprKind :: Lit ( left_lit) , ExprKind :: Lit ( right_lit) ) => left_lit. node == right_lit. node ,
81
- ( ExprKind :: Cast ( left_expr, left_ty) , ExprKind :: Cast ( right_expr, right_ty) )
82
- => mirrored_exprs ( cx, left_expr, a_ident, right_expr, b_ident) ,
83
- ( ExprKind :: DropTemps ( left) , ExprKind :: DropTemps ( right) ) => mirrored_exprs ( cx, left, a_ident, right, b_ident) ,
84
- ( ExprKind :: Field ( left_expr, left_ident) , ExprKind :: Field ( right_expr, right_ident) )
85
- => left_ident. name == right_ident. name && mirrored_exprs ( cx, left_expr, a_ident, right_expr, right_ident) ,
99
+ ( ExprKind :: Cast ( left, _) , ExprKind :: Cast ( right, _) ) => mirrored_exprs ( cx, left, a_ident, right, b_ident) ,
100
+ ( ExprKind :: DropTemps ( left_block) , ExprKind :: DropTemps ( right_block) ) => {
101
+ mirrored_exprs ( cx, left_block, a_ident, right_block, b_ident)
102
+ } ,
103
+ ( ExprKind :: Field ( left_expr, left_ident) , ExprKind :: Field ( right_expr, right_ident) ) => {
104
+ left_ident. name == right_ident. name && mirrored_exprs ( cx, left_expr, a_ident, right_expr, right_ident)
105
+ } ,
86
106
// Two paths: either one is a and the other is b, or they're identical to each other
87
- ( ExprKind :: Path ( QPath :: Resolved ( _, Path { segments : left_segments, .. } ) ) ,
88
- ExprKind :: Path ( QPath :: Resolved ( _, Path { segments : right_segments, .. } ) ) )
89
- => ( left_segments. iter ( ) . zip ( right_segments. iter ( ) ) . all ( |( left, right) | left. ident == right. ident )
90
- && left_segments. iter ( ) . all ( |seg| & seg. ident != a_ident && & seg. ident != b_ident) )
91
- || ( left_segments. len ( ) == 1 && & left_segments[ 0 ] . ident == a_ident && right_segments. len ( ) == 1 && & right_segments[ 0 ] . ident == b_ident) ,
107
+ (
108
+ ExprKind :: Path ( QPath :: Resolved (
109
+ _,
110
+ Path {
111
+ segments : left_segments,
112
+ ..
113
+ } ,
114
+ ) ) ,
115
+ ExprKind :: Path ( QPath :: Resolved (
116
+ _,
117
+ Path {
118
+ segments : right_segments,
119
+ ..
120
+ } ,
121
+ ) ) ,
122
+ ) => {
123
+ ( left_segments
124
+ . iter ( )
125
+ . zip ( right_segments. iter ( ) )
126
+ . all ( |( left, right) | left. ident == right. ident )
127
+ && left_segments
128
+ . iter ( )
129
+ . all ( |seg| & seg. ident != a_ident && & seg. ident != b_ident) )
130
+ || ( left_segments. len ( ) == 1
131
+ && & left_segments[ 0 ] . ident == a_ident
132
+ && right_segments. len ( ) == 1
133
+ && & right_segments[ 0 ] . ident == b_ident)
134
+ } ,
92
135
// Matching expressions, but one or both is borrowed
93
- ( ExprKind :: AddrOf ( left_kind, Mutability :: Not , left_expr) , ExprKind :: AddrOf ( right_kind, Mutability :: Not , right_expr) )
94
- => left_kind == right_kind && mirrored_exprs ( cx, left_expr, a_ident, right_expr, b_ident) ,
95
- ( _, ExprKind :: AddrOf ( _, Mutability :: Not , right_expr) )
96
- => mirrored_exprs ( cx, a_expr, a_ident, right_expr, b_ident) ,
97
- ( ExprKind :: AddrOf ( _, Mutability :: Not , left_expr) , _)
98
- => mirrored_exprs ( cx, left_expr, a_ident, b_expr, b_ident) ,
136
+ (
137
+ ExprKind :: AddrOf ( left_kind, Mutability :: Not , left_expr) ,
138
+ ExprKind :: AddrOf ( right_kind, Mutability :: Not , right_expr) ,
139
+ ) => left_kind == right_kind && mirrored_exprs ( cx, left_expr, a_ident, right_expr, b_ident) ,
140
+ ( _, ExprKind :: AddrOf ( _, Mutability :: Not , right_expr) ) => {
141
+ mirrored_exprs ( cx, a_expr, a_ident, right_expr, b_ident)
142
+ } ,
143
+ ( ExprKind :: AddrOf ( _, Mutability :: Not , left_expr) , _) => mirrored_exprs ( cx, left_expr, a_ident, b_expr, b_ident) ,
99
144
_ => false ,
100
- // (left, right) => {
101
- // println!("{:?}\n{:?}", left, right);
102
- // false
103
- // },
104
145
}
105
146
}
106
147
0 commit comments