Commit a3791fd
fix(read_env): advertise inline_completion only for the tags it sends
`read_env`'s `__attrs::query` was a member template, so it returned
`inline_completion` for every completion tag - even `set_stopped_t`,
which read_env never sends. That made `let_value` mistakenly classify
chains like
read_env(q) | let_value([](auto v) { return some_async_sender; })
as inline-completing. The check `__never_sends || behavior ==
inline_completion` passed for every tag because read_env claimed inline
across the board.
`__as_awaitable` then picked the inline `__sender_awaiter`, which holds
the operation state as a local in `await_suspend` and destroys it at the
closing brace. For any inner sender that hadn't actually completed by
then, this is a use-after-free.
Bind the query to the tags read_env actually completes with: always
`set_value_t`, and `set_error_t(exception_ptr)` when evaluating the
query throws - both complete inline within `start()`. `set_stopped_t`
now falls through to `__unknown`, so the inline check correctly fails
and the non-inline awaiter gets selected.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>1 parent 02d671d commit a3791fd
1 file changed
Lines changed: 7 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
80 | 80 | | |
81 | 81 | | |
82 | 82 | | |
83 | | - | |
84 | 83 | | |
85 | | - | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
86 | 91 | | |
87 | 92 | | |
88 | 93 | | |
| |||
0 commit comments