-
Notifications
You must be signed in to change notification settings - Fork 314
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix Itertools::k_smallest
on short unfused iterators
#900
Fix Itertools::k_smallest
on short unfused iterators
#900
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #900 +/- ##
==========================================
+ Coverage 94.38% 94.56% +0.17%
==========================================
Files 48 48
Lines 6665 6753 +88
==========================================
+ Hits 6291 6386 +95
+ Misses 374 367 -7 ☔ View full report in Codecov by Sentry. |
I'm exploring the possibility of buggy methods in the case of unfused iterators. EDIT: Well, after a short investigation, I found that only the https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b461adac3020a6f3e38087a56dd5cbd8 |
4057ef5
to
d787881
Compare
Itertools::k_smallest
on unfused iteratorsItertools::k_smallest
on short unfused iterators
I think we should fuse them: |
d787881
to
0936c8d
Compare
Explicitely fuse the iterator is also clearer than checking Done. And I did the same for the recent |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you.
I'm shocked! 😲 I found a bug in my favorite method!
In the case of an unfused iterator yielding at most k-1 elements, then None, then other elements, the heap is not k-long and
for_each
is called on the other elements leadingdebug_assert_eq
to rightfully panic.Our recent variants of
k_smallest
do not have this bug (the.len() ==
check is present)!Alternatively, iterators could be fused:
let mut iter = iter.fuse();
.I probably should add a test about this.
Story: After recently reviewing #654 where I deeply looked at
k_smallest
and its variants and my really recent #899 where I similarly thought of checking the length of the collected elements before callingfor_each
, I eventually/luckily saw this bug.