@@ -18,15 +18,25 @@ declare_clippy_lint! {
18
18
/// possible) than to use `Vec::sort_by` and and a more complicated
19
19
/// closure.
20
20
///
21
- /// **Known problems:** None.
21
+ /// **Known problems:**
22
+ /// If the suggested `Vec::sort_by_key` uses Reverse and it isn't
23
+ /// imported by a use statement in the current frame, then a `use`
24
+ /// statement that imports it will need to be added (which this lint
25
+ /// can't do).
22
26
///
23
27
/// **Example:**
24
28
///
25
29
/// ```rust
26
- /// vec.sort_by(|a, b| a.foo().cmp(b.foo()));
30
+ /// # struct A;
31
+ /// # impl A { fn foo(&self) {} }
32
+ /// # let mut vec: Vec<A> = Vec::new();
33
+ /// vec.sort_by(|a, b| a.foo().cmp(&b.foo()));
27
34
/// ```
28
35
/// Use instead:
29
36
/// ```rust
37
+ /// # struct A;
38
+ /// # impl A { fn foo(&self) {} }
39
+ /// # let mut vec: Vec<A> = Vec::new();
30
40
/// vec.sort_by_key(|a| a.foo());
31
41
/// ```
32
42
pub UNNECESSARY_SORT_BY ,
@@ -50,6 +60,7 @@ struct SortByKeyDetection {
50
60
vec_name : String ,
51
61
closure_arg : String ,
52
62
closure_body : String ,
63
+ reverse : bool ,
53
64
unstable : bool ,
54
65
}
55
66
@@ -172,16 +183,16 @@ fn detect_lint(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Option<LintTrigger>
172
183
if let ExprKind :: MethodCall ( method_path, _, [ ref left_expr, ref right_expr] ) = & closure_body. value. kind;
173
184
if method_path. ident. name. to_ident_string( ) == "cmp" ;
174
185
then {
175
- let ( closure_body, closure_arg) = if mirrored_exprs(
186
+ let ( closure_body, closure_arg, reverse ) = if mirrored_exprs(
176
187
& cx,
177
188
& left_expr,
178
189
& left_ident,
179
190
& right_expr,
180
191
& right_ident
181
192
) {
182
- ( Sugg :: hir( cx, & left_expr, ".." ) . to_string( ) , left_ident. name. to_string( ) )
193
+ ( Sugg :: hir( cx, & left_expr, ".." ) . to_string( ) , left_ident. name. to_string( ) , false )
183
194
} else if mirrored_exprs( & cx, & left_expr, & right_ident, & right_expr, & left_ident) {
184
- ( format! ( "Reverse({})" , Sugg :: hir( cx, & left_expr, ".." ) . to_string( ) ) , right_ident. name. to_string( ) )
195
+ ( Sugg :: hir( cx, & left_expr, ".." ) . to_string( ) , right_ident. name. to_string( ) , true )
185
196
} else {
186
197
return None ;
187
198
} ;
@@ -196,7 +207,13 @@ fn detect_lint(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Option<LintTrigger>
196
207
Some ( LintTrigger :: Sort ( SortDetection { vec_name, unstable } ) )
197
208
}
198
209
else {
199
- Some ( LintTrigger :: SortByKey ( SortByKeyDetection { vec_name, unstable, closure_arg, closure_body } ) )
210
+ Some ( LintTrigger :: SortByKey ( SortByKeyDetection {
211
+ vec_name,
212
+ unstable,
213
+ closure_arg,
214
+ closure_body,
215
+ reverse
216
+ } ) )
200
217
}
201
218
}
202
219
} else {
@@ -219,9 +236,17 @@ impl LateLintPass<'_, '_> for UnnecessarySortBy {
219
236
trigger. vec_name,
220
237
if trigger. unstable { "_unstable" } else { "" } ,
221
238
trigger. closure_arg,
222
- trigger. closure_body,
239
+ if trigger. reverse {
240
+ format!( "Reverse({})" , trigger. closure_body)
241
+ } else {
242
+ trigger. closure_body. to_string( )
243
+ } ,
223
244
) ,
224
- Applicability :: MachineApplicable ,
245
+ if trigger. reverse {
246
+ Applicability :: MaybeIncorrect
247
+ } else {
248
+ Applicability :: MachineApplicable
249
+ } ,
225
250
) ,
226
251
Some ( LintTrigger :: Sort ( trigger) ) => utils:: span_lint_and_sugg (
227
252
cx,
0 commit comments