@@ -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