join_me_maybe 0.6.0

an async `join!` macro with `select!`-like features
Documentation
# Agent Notes

This crate is a Rust proc-macro implementation of `join_me_maybe::join!`. Most
interesting bugs are state-machine bugs in generated code, especially around
cancellation, body scheduling, stream item buffering, and dropping things
promptly.

## Local Workflow

- Use tight timeouts when running tests that may deadlock, for example:
  `timeout 5s cargo test <test-name> -- --test-threads=1 --nocapture`. If you
  know you're running a single test, 1s is almost always enough.
- For macro expansion debugging, use `scripts/expand-example-scratch`. It writes
  scratch crates under `target/expand-scratch/`, adds the needed nightly feature
  gates, and keeps generated files out of normal Cargo builds.

## Semantics To Preserve

- Cancelled arms (both scrutinees and body/finally blocks) must not be polled
  again. This applies to both forms of cancellation, explicit `.cancel()` calls
  and also "maybe" arms after the "definitely" arms are finished.
- Cancelled arms, running bodies/finally expressions, and pending yielded items
  must be dropped before the macro yields back to its caller.
- Arm bodies run one at a time and may mutate shared local state.
- Streams are not polled concurrently with their own body. This is intentional.
- `finally` runs after natural stream completion, but not after cancellation.
- `maybe` arms are cancelled once all definitely scrutinees are finished; this
  does not require waiting for definitely bodies/finally expressions.

## Not Bugs

- `.cancel()` does not synchronously drop the target arm. It sets cancellation
  flags; cleanup happens at the macro's cleanup point before yielding to the
  caller. Do not add asserts that a cancelled scrutinee immediately appear as
  `None` via `with_pin_mut` or that e.g. `Mutex::try_lock` in another arm
  immediately succeeds.
- The same rule applies to implicit `maybe` cancellation after all definitely
  scrutinees finish. A definitely body may run before the cancelled maybe
  scrutinee has been physically dropped, as long as cleanup happens before the
  macro yields to its caller.
- Self-cancellation is allowed. An arm may call its own `.cancel()` and continue
  executing until its next `.await`; the implementation must not try to
  synchronously borrow/drop the currently executing arm in a way that panics.
- We don't currently force yields to the caller if the user provides an
  always-ready stream. In theory we could (if we invoked our own waker before
  yielding), but this is not currently considered a bug.