@@ -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 ///
@@ -1192,6 +1215,7 @@ declare_lint_pass!(Methods => [
11921215 SEARCH_IS_SOME ,
11931216 TEMPORARY_CSTRING_AS_PTR ,
11941217 FILTER_NEXT ,
1218+ SKIP_WHILE_NEXT ,
11951219 FILTER_MAP ,
11961220 FILTER_MAP_NEXT ,
11971221 FLAT_MAP_IDENTITY ,
@@ -1237,6 +1261,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
12371261 [ "map_or" , ..] => lint_map_or_none ( cx, expr, arg_lists[ 0 ] ) ,
12381262 [ "and_then" , ..] => lint_option_and_then_some ( cx, expr, arg_lists[ 0 ] ) ,
12391263 [ "next" , "filter" ] => lint_filter_next ( cx, expr, arg_lists[ 1 ] ) ,
1264+ [ "next" , "skip_while" ] => lint_skip_while_next ( cx, expr, arg_lists[ 1 ] ) ,
12401265 [ "map" , "filter" ] => lint_filter_map ( cx, expr, arg_lists[ 1 ] , arg_lists[ 0 ] ) ,
12411266 [ "map" , "filter_map" ] => lint_filter_map_map ( cx, expr, arg_lists[ 1 ] , arg_lists[ 0 ] ) ,
12421267 [ "next" , "filter_map" ] => lint_filter_map_next ( cx, expr, arg_lists[ 1 ] ) ,
@@ -2530,6 +2555,20 @@ fn lint_filter_next<'a, 'tcx>(
25302555 }
25312556}
25322557
2558+ /// lint use of `skip_while().next()` for `Iterators`
2559+ fn lint_skip_while_next < ' a , ' tcx > (
2560+ cx : & LateContext < ' a , ' tcx > ,
2561+ expr : & ' tcx hir:: Expr < ' _ > ,
2562+ _skip_while_args : & ' tcx [ hir:: Expr < ' _ > ] ,
2563+ ) {
2564+ // lint if caller of `.skip_while().next()` is an Iterator
2565+ if match_trait_method ( cx, expr, & paths:: ITERATOR ) {
2566+ let msg = "called `skip_while(p).next()` on an `Iterator`. \
2567+ This is more succinctly expressed by calling `.find(!p)` instead.";
2568+ span_lint ( cx, SKIP_WHILE_NEXT , expr. span , msg) ;
2569+ }
2570+ }
2571+
25332572/// lint use of `filter().map()` for `Iterators`
25342573fn lint_filter_map < ' a , ' tcx > (
25352574 cx : & LateContext < ' a , ' tcx > ,
0 commit comments