@@ -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:: { Expr , ExprKind , Mutability , Param , Pat , PatKind , Path , QPath } ;
6
+ use rustc_hir:: { Expr , ExprKind , Mutability , Param , Pat , PatKind , Path , PathSegment , 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 ;
@@ -16,7 +16,7 @@ declare_clippy_lint! {
16
16
/// **Why is this bad?**
17
17
/// It is more clear to use `Vec::sort_by_key` (or
18
18
/// `Vec::sort_by_key` and `std::cmp::Reverse` if necessary) than
19
- /// using
19
+ /// using
20
20
///
21
21
/// **Known problems:** None.
22
22
///
@@ -36,7 +36,17 @@ declare_clippy_lint! {
36
36
37
37
declare_lint_pass ! ( SortByKey => [ SORT_BY_KEY ] ) ;
38
38
39
- struct LintTrigger {
39
+ enum LintTrigger {
40
+ Sort ( SortDetection ) ,
41
+ SortByKey ( SortByKeyDetection ) ,
42
+ }
43
+
44
+ struct SortDetection {
45
+ vec_name : String ,
46
+ unstable : bool ,
47
+ }
48
+
49
+ struct SortByKeyDetection {
40
50
vec_name : String ,
41
51
closure_arg : String ,
42
52
closure_body : String ,
@@ -177,7 +187,18 @@ fn detect_lint(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Option<LintTrigger>
177
187
} ;
178
188
let vec_name = Sugg :: hir( cx, & args[ 0 ] , ".." ) . to_string( ) ;
179
189
let unstable = name == "sort_unstable_by" ;
180
- Some ( LintTrigger { vec_name, unstable, closure_arg, closure_body } )
190
+ if_chain! {
191
+ if let ExprKind :: Path ( QPath :: Resolved ( _, Path {
192
+ segments: [ PathSegment { ident: left_name, .. } ] , ..
193
+ } ) ) = & left_expr. kind;
194
+ if left_name == left_ident;
195
+ then {
196
+ Some ( LintTrigger :: Sort ( SortDetection { vec_name, unstable } ) )
197
+ }
198
+ else {
199
+ Some ( LintTrigger :: SortByKey ( SortByKeyDetection { vec_name, unstable, closure_arg, closure_body } ) )
200
+ }
201
+ }
181
202
} else {
182
203
None
183
204
}
@@ -186,8 +207,8 @@ fn detect_lint(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Option<LintTrigger>
186
207
187
208
impl LateLintPass < ' _ , ' _ > for SortByKey {
188
209
fn check_expr ( & mut self , cx : & LateContext < ' _ , ' _ > , expr : & Expr < ' _ > ) {
189
- if let Some ( trigger ) = detect_lint ( cx, expr) {
190
- utils:: span_lint_and_sugg (
210
+ match detect_lint ( cx, expr) {
211
+ Some ( LintTrigger :: SortByKey ( trigger ) ) => utils:: span_lint_and_sugg (
191
212
cx,
192
213
SORT_BY_KEY ,
193
214
expr. span ,
@@ -201,7 +222,21 @@ impl LateLintPass<'_, '_> for SortByKey {
201
222
trigger. closure_body,
202
223
) ,
203
224
Applicability :: MachineApplicable ,
204
- ) ;
225
+ ) ,
226
+ Some ( LintTrigger :: Sort ( trigger) ) => utils:: span_lint_and_sugg (
227
+ cx,
228
+ SORT_BY_KEY ,
229
+ expr. span ,
230
+ "use Vec::sort here instead" ,
231
+ "try" ,
232
+ format ! (
233
+ "{}.sort{}()" ,
234
+ trigger. vec_name,
235
+ if trigger. unstable { "_unstable" } else { "" } ,
236
+ ) ,
237
+ Applicability :: MachineApplicable ,
238
+ ) ,
239
+ None => { } ,
205
240
}
206
241
}
207
242
}
0 commit comments