@@ -44,6 +44,7 @@ mod option_as_ref_deref;
4444mod option_map_or_none;
4545mod option_map_unwrap_or;
4646mod or_fun_call;
47+ mod ref_mut_iter_method_chain;
4748mod search_is_some;
4849mod single_char_add_str;
4950mod single_char_insert_string;
@@ -1861,6 +1862,30 @@ declare_clippy_lint! {
18611862 "replace `.splitn(2, pat)` with `.split_once(pat)`"
18621863}
18631864
1865+ declare_clippy_lint ! {
1866+ /// ### What it does
1867+ /// Check for `&mut iter` followed by a method call.
1868+ ///
1869+ /// ### Why is this bad?
1870+ /// This requires using parenthesis to signify precedence.
1871+ ///
1872+ /// ### Example
1873+ /// ```rust
1874+ /// let mut iter = ['a', 'b', '.', 'd'].iter();
1875+ /// let before_dot = (&mut iter).take_while(|&&c| c != '.').collect::<Vec<_>>();
1876+ /// let after_dot = iter.collect::<Vec<_>>();
1877+ /// ```
1878+ /// Use instead:
1879+ /// ```rust
1880+ /// let mut iter = ['a', 'b', '.', 'd'].iter();
1881+ /// let before_dot = iter.by_ref().take_while(|&&c| c != '.').collect::<Vec<_>>();
1882+ /// let after_dot = iter.collect::<Vec<_>>();
1883+ /// ```
1884+ pub REF_MUT_ITER_METHOD_CHAIN ,
1885+ style,
1886+ "`&mut iter` used in a method chain"
1887+ }
1888+
18641889pub struct Methods {
18651890 avoid_breaking_exported_api : bool ,
18661891 msrv : Option < RustcVersion > ,
@@ -1939,7 +1964,8 @@ impl_lint_pass!(Methods => [
19391964 SUSPICIOUS_SPLITN ,
19401965 MANUAL_STR_REPEAT ,
19411966 EXTEND_WITH_DRAIN ,
1942- MANUAL_SPLIT_ONCE
1967+ MANUAL_SPLIT_ONCE ,
1968+ REF_MUT_ITER_METHOD_CHAIN
19431969] ) ;
19441970
19451971/// Extracts a method call name, args, and `Span` of the method name.
@@ -1973,7 +1999,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
19731999 hir:: ExprKind :: Call ( func, args) => {
19742000 from_iter_instead_of_collect:: check ( cx, expr, args, func) ;
19752001 } ,
1976- hir:: ExprKind :: MethodCall ( method_call, ref method_span, args, _) => {
2002+ hir:: ExprKind :: MethodCall ( method_call, ref method_span, args @ [ self_arg , .. ] , _) => {
19772003 or_fun_call:: check ( cx, expr, * method_span, & method_call. ident . as_str ( ) , args) ;
19782004 expect_fun_call:: check ( cx, expr, * method_span, & method_call. ident . as_str ( ) , args) ;
19792005 clone_on_copy:: check ( cx, expr, method_call. ident . name , args) ;
@@ -1982,6 +2008,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
19822008 single_char_add_str:: check ( cx, expr, args) ;
19832009 into_iter_on_ref:: check ( cx, expr, * method_span, method_call. ident . name , args) ;
19842010 single_char_pattern:: check ( cx, expr, method_call. ident . name , args) ;
2011+ ref_mut_iter_method_chain:: check ( cx, self_arg) ;
19852012 } ,
19862013 hir:: ExprKind :: Binary ( op, lhs, rhs) if op. node == hir:: BinOpKind :: Eq || op. node == hir:: BinOpKind :: Ne => {
19872014 let mut info = BinaryExprInfo {
0 commit comments