1- use clippy_utils:: diagnostics:: span_lint_and_sugg ;
1+ use clippy_utils:: diagnostics:: span_lint_and_then ;
22use clippy_utils:: is_trait_method;
3+ use clippy_utils:: path_to_local;
34use clippy_utils:: source:: snippet;
45use rustc_errors:: Applicability ;
56use rustc_hir as hir;
7+ use rustc_hir:: { BindingAnnotation , Node , PatKind } ;
68use rustc_lint:: LateContext ;
79use rustc_span:: sym;
810
@@ -11,14 +13,34 @@ use super::ITER_SKIP_NEXT;
1113pub ( super ) fn check ( cx : & LateContext < ' _ > , expr : & hir:: Expr < ' _ > , recv : & hir:: Expr < ' _ > , arg : & hir:: Expr < ' _ > ) {
1214 // lint if caller of skip is an Iterator
1315 if is_trait_method ( cx, expr, sym:: Iterator ) {
14- span_lint_and_sugg (
16+ let mut application = Applicability :: MachineApplicable ;
17+ span_lint_and_then (
1518 cx,
1619 ITER_SKIP_NEXT ,
1720 expr. span . trim_start ( recv. span ) . unwrap ( ) ,
1821 "called `skip(..).next()` on an iterator" ,
19- "use `nth` instead" ,
20- format ! ( ".nth({})" , snippet( cx, arg. span, ".." ) ) ,
21- Applicability :: MachineApplicable ,
22+ |diag| {
23+ if_chain ! {
24+ if let Some ( id) = path_to_local( recv) ;
25+ if let Node :: Binding ( pat) = cx. tcx. hir( ) . get( id) ;
26+ if let PatKind :: Binding ( ann, _, _, _) = pat. kind;
27+ if ann != BindingAnnotation :: Mutable ;
28+ then {
29+ application = Applicability :: Unspecified ;
30+ diag. span_help(
31+ pat. span,
32+ & format!( "for this change `{}` has to be mutable" , snippet( cx, pat. span, ".." ) ) ,
33+ ) ;
34+ }
35+ }
36+
37+ diag. span_suggestion (
38+ expr. span . trim_start ( recv. span ) . unwrap ( ) ,
39+ "use `nth` instead" ,
40+ format ! ( ".nth({})" , snippet( cx, arg. span, ".." ) ) ,
41+ application,
42+ ) ;
43+ } ,
2244 ) ;
2345 }
2446}
0 commit comments