Skip to content

Relax iterator Debug bounds on ExactlyOneError - #1132

Merged
phimuemue merged 3 commits into
rust-itertools:masterfrom
SAY-5:fix-exactly-one-error-debug-20261001
Oct 3, 2026
Merged

phimuemue merged 3 commits into
rust-itertools:masterfrom
SAY-5:fix-exactly-one-error-debug-20261001

Conversation

@SAY-5

@SAY-5 SAY-5 commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

ExactlyOneError currently requires the input iterator to implement Debug, so exactly_one().expect(...), at_most_one().expect(...), and ? into Box<dyn Error> fail for an opaque impl Iterator<Item = i32>.

Remove that unnecessary bound from Debug and Error. Keep the buffered first/second item diagnostics and mark the omitted inner iterator with ... Item: Debug is still required. Existing debug output therefore loses the inner iterator; iteration and Display are unchanged.

Fixes #1052.

At the maintainer's request, the four newly introduced tests were removed; both test files now match upstream. The production fix is unchanged. The removed regressions had previously demonstrated the original trait-bound failures on upstream and passed with the fix.

Validated after test removal on Rust 1.97.1, macOS ARM64:

  • 123 existing tests pass across test_core and test_std.
  • The 30 core tests pass separately with no default features and with use_alloc.
  • Formatting passes.

The earlier broader validation and baseline comparison remain historical evidence. Strict Clippy still has the previously identified unchanged question_mark warnings, and hosted semver/project-coverage failures remain unresolved. After the requested test removal, hosted patch coverage also reports one uncovered changed line (0% patch coverage); this check is failing. No warnings or checks were suppressed. MSRV, Miri and the full platform matrix were not rerun locally for this test-only follow-up.

AI assistance: OpenAI Codex assisted with the implementation, tests and description; a separate agent reviewed the patch and verification evidence.

@codecov

codecov Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 93.77%. Comparing base (6814180) to head (b723eec).
⚠️ Report is 220 commits behind head on master.

Files with missing lines Patch % Lines
src/exactly_one_err.rs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1132      +/-   ##
==========================================
- Coverage   94.38%   93.77%   -0.62%     
==========================================
  Files          48       52       +4     
  Lines        6665     6491     -174     
==========================================
- Hits         6291     6087     -204     
- Misses        374      404      +30     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread tests/test_core.rs Outdated

#[test]
fn exactly_one_without_debug_iterator() {
fn expect_one(iter: impl Iterator<Item = i32>) -> i32 {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove expect_one and just evaluate the result at the call site.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed expect_one in 1e61443. The assertion is now at the call site, using &mut dyn Iterator<Item = i32> so the test still catches the unwanted Debug bound.

Comment thread tests/test_core.rs Outdated
#[test]
fn at_most_one_without_debug_iterator() {
fn expect_at_most_one(iter: impl Iterator<Item = i32>) -> Option<i32> {
iter.at_most_one().expect("at most one item")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make expect_at_most_one accept the two arguments and pull the assert_eq into it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved assert_eq! into the two-argument expect_at_most_one helper in 1e61443.

Comment thread tests/test_std.rs Outdated
}

#[test]
fn exactly_one_error_debug_preserves_items() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a bit surprised to see this, because Debug::fmt takes &self, which inhibits calling next. Or am I missing something?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fmt only borrows &self; the call counter was unnecessary here. Removed it in 1e61443 while retaining the buffered-field formatting and item-recovery assertions.

Comment thread tests/test_std.rs Outdated
Ok(iter.exactly_one()?)
}

fn expect_at_most_one(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need the helper functions expect_at_most_one and expect_one?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed both helpers in 1e61443. The test now returns Result and exercises ? directly on Box<dyn Iterator<Item = i32>>; the failure cases still convert to Box<dyn Error>. The 127 tests in these two modules pass, as do the 32 core tests separately with no default features and with use_alloc. Restoring either old trait bound makes the corresponding regression checks fail.

@phimuemue phimuemue left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi there, thanks for this. Getting rid of the Debug bound is a good idea.

Can you address my other concerns regarding the tests?

@phimuemue

Copy link
Copy Markdown
Member

Sorry for my back and forth, but please remove the newly introduced tests. Server-Checks should detect if we mistakenly re-introduce the Debug bound

@SAY-5

SAY-5 commented Oct 3, 2026

Copy link
Copy Markdown
Contributor Author

Removed the four added tests in b723eec. Both test files now match upstream; the production change is unchanged. The remaining two test modules pass 123 tests, and the 30 core tests pass separately without default features and with use_alloc. Formatting passes.

@phimuemue
phimuemue enabled auto-merge October 3, 2026 13:06
@phimuemue

Copy link
Copy Markdown
Member

Thanks for this

@phimuemue
phimuemue added this pull request to the merge queue Oct 3, 2026
Merged via the queue into rust-itertools:master with commit 1681e07 Oct 3, 2026
7 of 14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ExactlyOneError doesn't always implement Debug

2 participants