|  | 
| 1 | 1 | mod char_indices_as_byte_indices; | 
|  | 2 | +mod const_sized_chunks; | 
| 2 | 3 | mod empty_loop; | 
| 3 | 4 | mod explicit_counter_loop; | 
| 4 | 5 | mod explicit_into_iter_loop; | 
| @@ -784,6 +785,107 @@ declare_clippy_lint! { | 
| 784 | 785 |     "using the character position yielded by `.chars().enumerate()` in a context where a byte index is expected" | 
| 785 | 786 | } | 
| 786 | 787 | 
 | 
|  | 788 | +declare_clippy_lint! { | 
|  | 789 | +    /// ### What it does | 
|  | 790 | +    /// Checks for usage of `.chunks_exact()` on slices where the `chunk_size` is a constant and suggests | 
|  | 791 | +    /// replacing it with its const generic equivalent, `.array_chunks()`, in a way that the value of the | 
|  | 792 | +    /// const parameter `N` can be inferred. | 
|  | 793 | +    /// | 
|  | 794 | +    /// Specifically, in a for-loop, consuming the iterator over the (non-overlapping) chunks, the lint | 
|  | 795 | +    /// suggests destructuring the chunks to allow for `N`, the number of elements in a chunk, to be inferred. | 
|  | 796 | +    /// | 
|  | 797 | +    /// ### Why is this bad? | 
|  | 798 | +    /// When `.chunks_exact()` is used, a bounds check is required before an element can be accessed. | 
|  | 799 | +    /// | 
|  | 800 | +    /// ### Example | 
|  | 801 | +    /// ```no_run | 
|  | 802 | +    /// let numbers = Vec::from_iter(0..10); | 
|  | 803 | +    /// for chunk in numbers.chunks_exact(2) { | 
|  | 804 | +    ///     println!("{n} is an odd number", n = chunk[1]); | 
|  | 805 | +    /// } | 
|  | 806 | +    /// ``` | 
|  | 807 | +    /// Use instead: | 
|  | 808 | +    /// ```no_run | 
|  | 809 | +    /// #![feature(array_chunks)] | 
|  | 810 | +    /// let numbers = Vec::from_iter(0..10); | 
|  | 811 | +    /// for [_, n] in numbers.array_chunks() { | 
|  | 812 | +    ///     println!("{n} is an odd number"); | 
|  | 813 | +    /// } | 
|  | 814 | +    /// ``` | 
|  | 815 | +    #[clippy::version = "1.89.0"] | 
|  | 816 | +    pub CONST_SIZED_CHUNKS_EXACT, | 
|  | 817 | +    nursery, | 
|  | 818 | +    "calling `.chunks_exact()` with a constant `chunk_size` where `.array_chunks()` could be used instead" | 
|  | 819 | +} | 
|  | 820 | + | 
|  | 821 | +declare_clippy_lint! { | 
|  | 822 | +    /// ### What it does | 
|  | 823 | +    /// Checks for usage of `.chunks_exact_mut()` on slices where the `chunk_size` is a constant and suggests | 
|  | 824 | +    /// replacing it with its const generic equivalent, `.array_chunks_mut()`, in a way that the value of the | 
|  | 825 | +    /// const parameter `N` can be inferred. | 
|  | 826 | +    /// | 
|  | 827 | +    /// Specifically, in a for-loop, consuming the iterator over the (non-overlapping) chunks, the lint | 
|  | 828 | +    /// suggests destructuring the chunks to allow for `N`, the number of elements in a chunk, to be inferred. | 
|  | 829 | +    /// | 
|  | 830 | +    /// ### Why is this bad? | 
|  | 831 | +    /// When `.chunks_exact_mut()` is used, a bounds check is required before an element can be accessed. | 
|  | 832 | +    /// | 
|  | 833 | +    /// ### Example | 
|  | 834 | +    /// ```no_run | 
|  | 835 | +    /// let mut numbers = Vec::from_iter(0..10); | 
|  | 836 | +    /// for chunk in numbers.chunks_exact_mut(2) { | 
|  | 837 | +    ///     chunk[1] += chunk[0]; | 
|  | 838 | +    ///     println!("{n} is an odd number", n = chunk[1]); | 
|  | 839 | +    /// } | 
|  | 840 | +    /// ``` | 
|  | 841 | +    /// Use instead: | 
|  | 842 | +    /// ```no_run | 
|  | 843 | +    /// #![feature(array_chunks)] | 
|  | 844 | +    /// let mut numbers = Vec::from_iter(0..10); | 
|  | 845 | +    /// for [m, n] in numbers.array_chunks_mut() { | 
|  | 846 | +    ///     *n += *m; | 
|  | 847 | +    ///     println!("{n} is an odd number"); | 
|  | 848 | +    /// } | 
|  | 849 | +    /// ``` | 
|  | 850 | +    #[clippy::version = "1.89.0"] | 
|  | 851 | +    pub CONST_SIZED_CHUNKS_EXACT_MUT, | 
|  | 852 | +    nursery, | 
|  | 853 | +    "calling `.chunks_exact_mut()` with a constant `chunk_size` where `.array_chunks_mut()` could be used instead" | 
|  | 854 | +} | 
|  | 855 | + | 
|  | 856 | +declare_clippy_lint! { | 
|  | 857 | +    /// ### What it does | 
|  | 858 | +    /// Checks for usage of `.windows()` on slices where the `size` is a constant and suggests replacing it with | 
|  | 859 | +    /// its const generic equivalent, `.array_windows()`, in a way that the value of the const parameter `N` can | 
|  | 860 | +    /// be inferred. | 
|  | 861 | +    /// | 
|  | 862 | +    /// Specifically, in a for-loop, consuming the windowed iterator over the overlapping chunks, the lint | 
|  | 863 | +    /// suggests destructuring the chunks to allow for `N`, the number of elements in a chunk, to be inferred. | 
|  | 864 | +    /// | 
|  | 865 | +    /// ### Why is this bad? | 
|  | 866 | +    /// When `.windows()` is used, a bounds check is required before an element can be accessed. | 
|  | 867 | +    /// | 
|  | 868 | +    /// ### Example | 
|  | 869 | +    /// ```no_run | 
|  | 870 | +    /// let numbers = Vec::from_iter(0..10); | 
|  | 871 | +    /// for chunk in numbers.windows(2) { | 
|  | 872 | +    ///     println!("{n} is an odd number", n = chunk[0] + chunk[1]); | 
|  | 873 | +    /// } | 
|  | 874 | +    /// ``` | 
|  | 875 | +    /// Use instead: | 
|  | 876 | +    /// ```no_run | 
|  | 877 | +    /// #![feature(array_windows)] | 
|  | 878 | +    /// let numbers = Vec::from_iter(0..10); | 
|  | 879 | +    /// for [m, n] in numbers.array_windows() { | 
|  | 880 | +    ///     println!("{n} is an odd number", n = m + n); | 
|  | 881 | +    /// } | 
|  | 882 | +    /// ``` | 
|  | 883 | +    #[clippy::version = "1.89.0"] | 
|  | 884 | +    pub CONST_SIZED_WINDOWS, | 
|  | 885 | +    nursery, | 
|  | 886 | +    "calling `.windows()` with a constant `size` where `.array_windows()` could be used instead" | 
|  | 887 | +} | 
|  | 888 | + | 
| 787 | 889 | pub struct Loops { | 
| 788 | 890 |     msrv: Msrv, | 
| 789 | 891 |     enforce_iter_loop_reborrow: bool, | 
| @@ -822,6 +924,9 @@ impl_lint_pass!(Loops => [ | 
| 822 | 924 |     INFINITE_LOOP, | 
| 823 | 925 |     MANUAL_SLICE_FILL, | 
| 824 | 926 |     CHAR_INDICES_AS_BYTE_INDICES, | 
|  | 927 | +    CONST_SIZED_CHUNKS_EXACT, | 
|  | 928 | +    CONST_SIZED_CHUNKS_EXACT_MUT, | 
|  | 929 | +    CONST_SIZED_WINDOWS, | 
| 825 | 930 | ]); | 
| 826 | 931 | 
 | 
| 827 | 932 | impl<'tcx> LateLintPass<'tcx> for Loops { | 
| @@ -906,6 +1011,7 @@ impl Loops { | 
| 906 | 1011 |         manual_find::check(cx, pat, arg, body, span, expr); | 
| 907 | 1012 |         unused_enumerate_index::check(cx, pat, arg, body); | 
| 908 | 1013 |         char_indices_as_byte_indices::check(cx, pat, arg, body); | 
|  | 1014 | +        const_sized_chunks::check(cx, pat, arg); | 
| 909 | 1015 |     } | 
| 910 | 1016 | 
 | 
| 911 | 1017 |     fn check_for_loop_arg(&self, cx: &LateContext<'_>, _: &Pat<'_>, arg: &Expr<'_>) { | 
|  | 
0 commit comments