@@ -3,7 +3,7 @@ use crate::utils::paths;
33use crate :: utils:: sugg:: Sugg ;
44use if_chain:: if_chain;
55use 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 } ;
77use rustc_lint:: { LateContext , LateLintPass } ;
88use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
99use rustc_span:: symbol:: Ident ;
@@ -16,7 +16,7 @@ declare_clippy_lint! {
1616 /// **Why is this bad?**
1717 /// It is more clear to use `Vec::sort_by_key` (or
1818 /// `Vec::sort_by_key` and `std::cmp::Reverse` if necessary) than
19- /// using
19+ /// using
2020 ///
2121 /// **Known problems:** None.
2222 ///
@@ -36,7 +36,17 @@ declare_clippy_lint! {
3636
3737declare_lint_pass ! ( SortByKey => [ SORT_BY_KEY ] ) ;
3838
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 {
4050 vec_name : String ,
4151 closure_arg : String ,
4252 closure_body : String ,
@@ -177,7 +187,18 @@ fn detect_lint(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Option<LintTrigger>
177187 } ;
178188 let vec_name = Sugg :: hir( cx, & args[ 0 ] , ".." ) . to_string( ) ;
179189 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+ }
181202 } else {
182203 None
183204 }
@@ -186,8 +207,8 @@ fn detect_lint(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Option<LintTrigger>
186207
187208impl LateLintPass < ' _ , ' _ > for SortByKey {
188209 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 (
191212 cx,
192213 SORT_BY_KEY ,
193214 expr. span ,
@@ -201,7 +222,21 @@ impl LateLintPass<'_, '_> for SortByKey {
201222 trigger. closure_body,
202223 ) ,
203224 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 => { } ,
205240 }
206241 }
207242}
0 commit comments