fix: LcVarsIterMut::size_hint off-by-one and potential underflow#412
Conversation
There was a problem hiding this comment.
Pull Request Overview
Fixes an off-by-one error and potential underflow in the LcVarsIterMut::size_hint method by using the correct window count calculation.
Key Changes
- Changed
self.offsets.len() - 1toself.offsets.len()in the size_hint calculation - Prevents potential underflow when the iterator is empty
- Aligns with core::slice::Windows semantics for accurate iteration hints
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| #[inline] | ||
| fn size_hint(&self) -> (usize, Option<usize>) { | ||
| let len = self.offsets.len() - 1; | ||
| let len = self.offsets.len(); |
There was a problem hiding this comment.
This change may introduce an off-by-one error in the opposite direction. If LcVarsIterMut is iterating over windows of consecutive elements (similar to slice::windows()), then the number of windows should be offsets.len() - window_size + 1, not offsets.len(). Please verify that self.offsets.len() actually represents the correct count of remaining items to iterate over, rather than the total number of offset positions.
There was a problem hiding this comment.
hm could you please check this case as well? Thank you!
There was a problem hiding this comment.
hm could you please check this case as well? Thank you!
In LcVarsIterMut the field named offsets is actually a Windows<'_, usize> iterator (from offsets.windows(2)), not the raw offsets slice. For Windows, .len() already equals “how many windows are left.” So size_hint should use (len, Some(len)) as-is.
- If we subtracted 1 here, we’d undercount and also break the empty case; the new test covers that and would fail.
- In the parallel path we do use the raw slice, so we correctly use offsets.len().saturating_sub(1). Both paths are consistent.
So the current size_hint is correct, and the test is right.
|
Can you add a test which demonstrates this is an issue? |
Yes, done |
Use Windows::len() directly as the exact number of remaining windows instead of subtracting 1.
The previous implementation self.offsets.len() - 1 underestimated the remaining items and could underflow when the iterator was empty (panic in debug, wrap in release).
This aligns size_hint with the semantics of core::slice::Windows, ensuring accurate iteration hints and avoiding edge-case failures.