@@ -44,6 +44,7 @@ mod option_as_ref_deref;
44
44
mod option_map_or_none;
45
45
mod option_map_unwrap_or;
46
46
mod or_fun_call;
47
+ mod ref_mut_iter_method_chain;
47
48
mod search_is_some;
48
49
mod single_char_add_str;
49
50
mod single_char_insert_string;
@@ -1796,6 +1797,30 @@ declare_clippy_lint! {
1796
1797
"replace `.splitn(2, pat)` with `.split_once(pat)`"
1797
1798
}
1798
1799
1800
+ declare_clippy_lint ! {
1801
+ /// ### What it does
1802
+ /// Check for `&mut iter` followed by a method call.
1803
+ ///
1804
+ /// ### Why is this bad?
1805
+ /// This requires using parenthesis to signify precedence.
1806
+ ///
1807
+ /// ### Example
1808
+ /// ```rust
1809
+ /// let mut iter = ['a', 'b', '.', 'd'].iter();
1810
+ /// let before_dot = (&mut iter).take_while(|&&c| c != '.').collect::<Vec<_>>();
1811
+ /// let after_dot = iter.collect::<Vec<_>>();
1812
+ /// ```
1813
+ /// Use instead:
1814
+ /// ```rust
1815
+ /// let mut iter = ['a', 'b', '.', 'd'].iter();
1816
+ /// let before_dot = iter.by_ref().take_while(|&&c| c != '.').collect::<Vec<_>>();
1817
+ /// let after_dot = iter.collect::<Vec<_>>();
1818
+ /// ```
1819
+ pub REF_MUT_ITER_METHOD_CHAIN ,
1820
+ style,
1821
+ "`&mut iter` used in a method chain"
1822
+ }
1823
+
1799
1824
pub struct Methods {
1800
1825
avoid_breaking_exported_api : bool ,
1801
1826
msrv : Option < RustcVersion > ,
@@ -1874,7 +1899,8 @@ impl_lint_pass!(Methods => [
1874
1899
SUSPICIOUS_SPLITN ,
1875
1900
MANUAL_STR_REPEAT ,
1876
1901
EXTEND_WITH_DRAIN ,
1877
- MANUAL_SPLIT_ONCE
1902
+ MANUAL_SPLIT_ONCE ,
1903
+ REF_MUT_ITER_METHOD_CHAIN
1878
1904
] ) ;
1879
1905
1880
1906
/// Extracts a method call name, args, and `Span` of the method name.
@@ -1908,7 +1934,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
1908
1934
hir:: ExprKind :: Call ( func, args) => {
1909
1935
from_iter_instead_of_collect:: check ( cx, expr, args, func) ;
1910
1936
} ,
1911
- hir:: ExprKind :: MethodCall ( method_call, ref method_span, args, _) => {
1937
+ hir:: ExprKind :: MethodCall ( method_call, ref method_span, args @ [ self_arg , .. ] , _) => {
1912
1938
or_fun_call:: check ( cx, expr, * method_span, & method_call. ident . as_str ( ) , args) ;
1913
1939
expect_fun_call:: check ( cx, expr, * method_span, & method_call. ident . as_str ( ) , args) ;
1914
1940
clone_on_copy:: check ( cx, expr, method_call. ident . name , args) ;
@@ -1917,6 +1943,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
1917
1943
single_char_add_str:: check ( cx, expr, args) ;
1918
1944
into_iter_on_ref:: check ( cx, expr, * method_span, method_call. ident . name , args) ;
1919
1945
single_char_pattern:: check ( cx, expr, method_call. ident . name , args) ;
1946
+ ref_mut_iter_method_chain:: check ( cx, self_arg) ;
1920
1947
} ,
1921
1948
hir:: ExprKind :: Binary ( op, lhs, rhs) if op. node == hir:: BinOpKind :: Eq || op. node == hir:: BinOpKind :: Ne => {
1922
1949
let mut info = BinaryExprInfo {
0 commit comments