Visitar URL original
channel: Implement Display and Error for TryReadyError and ReadyTimeoutError by MaxFreedomPollard · Pull Request #1327 · crossbeam-rs/crossbeam · GitHub
Skip to content

channel: Implement Display and Error for TryReadyError and ReadyTimeoutError - #1327

Merged
taiki-e merged 1 commit into
crossbeam-rs:mainfrom
MaxFreedomPollard:channel-ready-error-impls
Sep 7, 2026
Merged

taiki-e merged 1 commit into
crossbeam-rs:mainfrom
MaxFreedomPollard:channel-ready-error-impls

Conversation

@MaxFreedomPollard

Copy link
Copy Markdown
Contributor

TryReadyError and ReadyTimeoutError are public, re-exported from crossbeam-channel/src/lib.rs:383, and are what Select::try_ready, Select::ready_timeout and Select::ready_deadline return. They are the only error types in crossbeam-channel/src/err.rs that implement neither fmt::Display nor std::error::Error, so the select side works and the ready side does not:

// fine
let _: Box<dyn std::error::Error> = Box::new(crossbeam_channel::SelectTimeoutError);
// error[E0277]: the trait bound `ReadyTimeoutError: std::error::Error` is not satisfied
let _: Box<dyn std::error::Error> = Box::new(crossbeam_channel::ReadyTimeoutError);

In practice that means sel.ready_timeout(d)? does not compile in a function returning Box<dyn Error> or anyhow::Result, while sel.select_timeout(d)? does, and println!("{err}") on either ready error does not compile at all. Today only Debug is available, from the derive on the two structs.

This adds the two Display impls and the two empty error::Error impls at the end of err.rs, which keeps the impls in the order the types are declared. The messages are the ones already used by the select counterparts at crossbeam-channel/src/err.rs:340-354. TrySelectError and TryReadyError carry the same doc line, "Failed because none of the channel operations were ready.", so both say "all operations in select would block"; SelectTimeoutError and ReadyTimeoutError carry the same doc line, "Failed because none of the channel operations became ready before the timeout.", so both say "timed out waiting on select".

error_impls in crossbeam-channel/tests/ready.rs boxes each error as Box<dyn Error> and asserts the rendered text. It runs on one thread with no sleeps and no timing assumptions, so it is fine under Miri and on every CI target. ready_timeout(ms(0)) reaches the deadline branch of run_ready deterministically, because ready_timeout computes the deadline as Instant::now() before the readiness scan and the scan is what advances the clock past it. The sender stays bound as _s so the channel is connected and never ready.

Verified on macOS aarch64 with cargo 1.95.0:

  • Without the err.rs change, cargo test -p crossbeam-channel --test ready error_impls fails to build with two error[E0277], one per type.
  • With it, test error_impls ... ok.
  • cargo test -p crossbeam-channel: 400 passed, 0 failed, 1 ignored across 15 test binaries, plus 74 doctests passed.
  • cargo clippy -p crossbeam-channel --lib --tests -- -D warnings: clean. --all-targets cannot be used on stable here because benches/crossbeam.rs opens with #![feature(test)]; that fails identically on an unmodified checkout.
  • cargo fmt --all -- --check: clean.

Nothing public is removed or changed, so the addition is backwards compatible.

…utError

TryReadyError and ReadyTimeoutError are public error types, re-exported
from crossbeam-channel/src/lib.rs:383 and returned by Select::try_ready,
Select::ready_timeout and Select::ready_deadline. They were the only
error types in crossbeam-channel/src/err.rs that implement neither
fmt::Display nor std::error::Error, so `sel.ready_timeout(d)?` fails to
compile in a function returning Box<dyn Error>, and the error cannot be
printed with `{}`.

Their select counterparts, TrySelectError and SelectTimeoutError at
crossbeam-channel/src/err.rs:340-354, carry doc comments that are word
for word identical, so this reuses their messages: "all operations in
select would block" and "timed out waiting on select". The new impls go
at the end of err.rs, keeping the impl order the same as the order in
which the types are declared.

The new error_impls test in crossbeam-channel/tests/ready.rs boxes both
errors as Box<dyn Error> and checks the rendered text. It fails to
compile without the impls (E0277) and uses no threads, sleeps or timing.

@taiki-e taiki-e 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.

Thanks!

@taiki-e
taiki-e merged commit 38dacb4 into crossbeam-rs:main Sep 7, 2026
30 checks passed
@taiki-e taiki-e mentioned this pull request Sep 7, 2026
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

2 participants