@@ -375,6 +375,29 @@ declare_clippy_lint! {
375375 "using `filter(p).next()`, which is more succinctly expressed as `.find(p)`"
376376}
377377
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+
378401declare_clippy_lint ! {
379402 /// **What it does:** Checks for usage of `_.map(_).flatten(_)`,
380403 ///
@@ -1193,6 +1216,7 @@ declare_lint_pass!(Methods => [
11931216 SEARCH_IS_SOME ,
11941217 TEMPORARY_CSTRING_AS_PTR ,
11951218 FILTER_NEXT ,
1219+ SKIP_WHILE_NEXT ,
11961220 FILTER_MAP ,
11971221 FILTER_MAP_NEXT ,
11981222 FLAT_MAP_IDENTITY ,
@@ -1238,6 +1262,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
12381262 [ "map_or" , ..] => lint_map_or_none ( cx, expr, arg_lists[ 0 ] ) ,
12391263 [ "and_then" , ..] => lint_option_and_then_some ( cx, expr, arg_lists[ 0 ] ) ,
12401264 [ "next" , "filter" ] => lint_filter_next ( cx, expr, arg_lists[ 1 ] ) ,
1265+ [ "next" , "skip_while" ] => lint_skip_while_next ( cx, expr, arg_lists[ 1 ] ) ,
12411266 [ "map" , "filter" ] => lint_filter_map ( cx, expr, arg_lists[ 1 ] , arg_lists[ 0 ] ) ,
12421267 [ "map" , "filter_map" ] => lint_filter_map_map ( cx, expr, arg_lists[ 1 ] , arg_lists[ 0 ] ) ,
12431268 [ "next" , "filter_map" ] => lint_filter_map_next ( cx, expr, arg_lists[ 1 ] ) ,
@@ -2531,6 +2556,24 @@ fn lint_filter_next<'a, 'tcx>(
25312556 }
25322557}
25332558
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+
25342577/// lint use of `filter().map()` for `Iterators`
25352578fn lint_filter_map < ' a , ' tcx > (
25362579 cx : & LateContext < ' a , ' tcx > ,
0 commit comments