@@ -375,6 +375,29 @@ declare_clippy_lint! {
375
375
"using `filter(p).next()`, which is more succinctly expressed as `.find(p)`"
376
376
}
377
377
378
+ declare_clippy_lint ! {
379
+ /// **What it does:** Checks for usage of `_.skip_while(condition).next()`.
380
+ ///
381
+ /// **Why is this bad?** Readability, this can be written more concisely as
382
+ /// `_.find(!condition)`.
383
+ ///
384
+ /// **Known problems:** None.
385
+ ///
386
+ /// **Example:**
387
+ /// ```rust
388
+ /// # let vec = vec![1];
389
+ /// vec.iter().skip_while(|x| **x == 0).next();
390
+ /// ```
391
+ /// Could be written as
392
+ /// ```rust
393
+ /// # let vec = vec![1];
394
+ /// vec.iter().find(|x| **x != 0);
395
+ /// ```
396
+ pub SKIP_WHILE_NEXT ,
397
+ complexity,
398
+ "using `skip_while(p).next()`, which is more succinctly expressed as `.find(!p)`"
399
+ }
400
+
378
401
declare_clippy_lint ! {
379
402
/// **What it does:** Checks for usage of `_.map(_).flatten(_)`,
380
403
///
@@ -1193,6 +1216,7 @@ declare_lint_pass!(Methods => [
1193
1216
SEARCH_IS_SOME ,
1194
1217
TEMPORARY_CSTRING_AS_PTR ,
1195
1218
FILTER_NEXT ,
1219
+ SKIP_WHILE_NEXT ,
1196
1220
FILTER_MAP ,
1197
1221
FILTER_MAP_NEXT ,
1198
1222
FLAT_MAP_IDENTITY ,
@@ -1238,6 +1262,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
1238
1262
[ "map_or" , ..] => lint_map_or_none ( cx, expr, arg_lists[ 0 ] ) ,
1239
1263
[ "and_then" , ..] => lint_option_and_then_some ( cx, expr, arg_lists[ 0 ] ) ,
1240
1264
[ "next" , "filter" ] => lint_filter_next ( cx, expr, arg_lists[ 1 ] ) ,
1265
+ [ "next" , "skip_while" ] => lint_skip_while_next ( cx, expr, arg_lists[ 1 ] ) ,
1241
1266
[ "map" , "filter" ] => lint_filter_map ( cx, expr, arg_lists[ 1 ] , arg_lists[ 0 ] ) ,
1242
1267
[ "map" , "filter_map" ] => lint_filter_map_map ( cx, expr, arg_lists[ 1 ] , arg_lists[ 0 ] ) ,
1243
1268
[ "next" , "filter_map" ] => lint_filter_map_next ( cx, expr, arg_lists[ 1 ] ) ,
@@ -2531,6 +2556,24 @@ fn lint_filter_next<'a, 'tcx>(
2531
2556
}
2532
2557
}
2533
2558
2559
+ /// lint use of `skip_while().next()` for `Iterators`
2560
+ fn lint_skip_while_next < ' a , ' tcx > (
2561
+ cx : & LateContext < ' a , ' tcx > ,
2562
+ expr : & ' tcx hir:: Expr < ' _ > ,
2563
+ _skip_while_args : & ' tcx [ hir:: Expr < ' _ > ] ,
2564
+ ) {
2565
+ // lint if caller of `.skip_while().next()` is an Iterator
2566
+ if match_trait_method ( cx, expr, & paths:: ITERATOR ) {
2567
+ span_help_and_lint (
2568
+ cx,
2569
+ SKIP_WHILE_NEXT ,
2570
+ expr. span ,
2571
+ "called `skip_while(p).next()` on an `Iterator`" ,
2572
+ "this is more succinctly expressed by calling `.find(!p)` instead" ,
2573
+ ) ;
2574
+ }
2575
+ }
2576
+
2534
2577
/// lint use of `filter().map()` for `Iterators`
2535
2578
fn lint_filter_map < ' a , ' tcx > (
2536
2579
cx : & LateContext < ' a , ' tcx > ,
0 commit comments