@@ -4,6 +4,7 @@ mod explicit_counter_loop;
44mod explicit_into_iter_loop;
55mod explicit_iter_loop;
66mod for_kv_map;
7+ mod for_unbounded_range;
78mod infinite_loop;
89mod iter_next_loop;
910mod manual_find;
@@ -236,6 +237,35 @@ declare_clippy_lint! {
236237 "looping on a map using `iter` when `keys` or `values` would do"
237238}
238239
240+ declare_clippy_lint ! {
241+ /// ### What it does
242+ /// Checks for unbounded for loops over char or integers.
243+ ///
244+ /// ### Why is this bad?
245+ /// Using a unbounded range over char and integers will unexpectedly not handle overflows so it will lead to panics
246+ /// or infinite loops.
247+ ///
248+ /// Instead there should be a max value set, usually the `MAX` constant for a given type such as `'\0'..char::MAX`
249+ /// or `250..u8::MAX`.
250+ ///
251+ /// ### Example
252+ /// ```no_run
253+ /// for i in 250u8.. {
254+ /// println!("{i}");
255+ /// }
256+ /// ```
257+ /// Use instead:
258+ /// ```no_run
259+ /// for i in 250u8..=u8::MAX {
260+ /// println!("{i}");
261+ /// }
262+ /// ```
263+ #[ clippy:: version = "1.98.0" ]
264+ pub FOR_UNBOUNDED_RANGE ,
265+ suspicious,
266+ "using a for loop over unbounded range such as `0..`"
267+ }
268+
239269declare_clippy_lint ! {
240270 /// ### What it does
241271 /// Checks for infinite loops in a function where the return type is not `!`
@@ -792,6 +822,7 @@ impl_lint_pass!(Loops => [
792822 EXPLICIT_INTO_ITER_LOOP ,
793823 EXPLICIT_ITER_LOOP ,
794824 FOR_KV_MAP ,
825+ FOR_UNBOUNDED_RANGE ,
795826 INFINITE_LOOP ,
796827 ITER_NEXT_LOOP ,
797828 MANUAL_FIND ,
@@ -951,6 +982,7 @@ impl Loops {
951982 manual_find:: check ( cx, pat, arg, body, span, expr) ;
952983 unused_enumerate_index:: check ( cx, arg, pat, None , body) ;
953984 char_indices_as_byte_indices:: check ( cx, pat, arg, body) ;
985+ for_unbounded_range:: check ( cx, label, arg, span, body) ;
954986 }
955987
956988 fn check_for_loop_arg ( & self , cx : & LateContext < ' _ > , _: & Pat < ' _ > , arg : & Expr < ' _ > ) {
0 commit comments