From fbd4c9a7c51e9b4882553a12c9e81bf1771fb599 Mon Sep 17 00:00:00 2001 From: Charlie Tonneslan Date: Sun, 17 May 2026 13:10:35 -0400 Subject: [PATCH] InterleaveShortest: don't overflow size_hint lower bound The combined lower bound was computed with saturating_mul, so could already be at usize::MAX, and then the unchecked +1 would panic in debug builds when both halves of the interleave reported large lower bounds (e.g. an Iterator::take(usize::MAX) interleaved with iter::repeat). Switch to saturating_add. Closes #1068. Signed-off-by: Charlie Tonneslan --- src/adaptors/mod.rs | 2 +- tests/test_std.rs | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/adaptors/mod.rs b/src/adaptors/mod.rs index b5c0d42b1..451a4ee77 100644 --- a/src/adaptors/mod.rs +++ b/src/adaptors/mod.rs @@ -179,7 +179,7 @@ where let (combined_lower, combined_upper) = size_hint::mul_scalar(size_hint::min(curr_hint, next_hint), 2); let lower = if curr_lower > next_lower { - combined_lower + 1 + combined_lower.saturating_add(1) } else { combined_lower }; diff --git a/tests/test_std.rs b/tests/test_std.rs index e1bd8cbbc..de8d660f0 100644 --- a/tests/test_std.rs +++ b/tests/test_std.rs @@ -83,6 +83,14 @@ fn interleave_shortest() { let i1 = ::std::iter::repeat(1); let it = v0.into_iter().interleave_shortest(i1); assert_eq!(it.size_hint(), (6, Some(6))); + + // Issue #1068: combined lower bound used to overflow when both halves + // reported saturating lower bounds, panicking in debug builds. + let i0 = ::std::iter::repeat(0).take(usize::MAX); + let i1 = ::std::iter::repeat(1); + let it = i0.interleave_shortest(i1); + let (lower, _) = it.size_hint(); + assert_eq!(lower, usize::MAX); } #[test]