Commit fb64539
authored
client: restore Send on stream message() futures with concrete view types (#215)
Fixes #214.
**Before** (0.8.0 — fails to compile with any concrete generated view
type):
```rust
tokio::spawn(async move {
while let Some(msg) = stream.message().await? { /* … */ }
});
// error: implementation of `MessageView` is not general enough
```
**After**: the same code compiles and runs; verified live with a spawned
consumer on a multi-threaded runtime across server-stream,
mid-stream-error, and bidi shapes.
## Root cause
The 0.8.0 client-stream change bounded both `message()` methods with
`RespView::Owned: HasMessageView<View<'static> = RespView>`. Projecting
through the GAT inside an `async fn`'s where-clause trips rustc's
coroutine-witness auto-trait check on monomorphization — the future is
`Send` when the message type is a generic parameter but loses `Send`
with any concrete generated type, exactly as isolated in the issue
(whose report was excellent — the generic-vs-concrete observation
pointed straight at the fix).
## The fix
Reshape the bound as an output type parameter:
```rust
pub async fn message<M>(&mut self) -> Result<Option<StreamMessage<M>>, ConnectError>
where
RespView: MessageView<'static, Owned = M>,
M: HasMessageView<View<'static> = RespView>,
```
`M` is uniquely determined by `RespView` (the impl blocks already carry
`RespView: MessageView<'static>`), so the bound is logically equivalent
and `M` is inferred at every call site — the entire workspace compiles
with zero call-site changes.
The regression pin in `tests/streaming` asserts `Send` through
async-block wrappers deliberately: the bare `message()` future is `Send`
even with the buggy bound — the failure only manifests in the
*enclosing* coroutine's witness, i.e. exactly the `tokio::spawn(async
move { .. })` shape users write. Verified fail-before (4 errors) /
pass-after, and covered by concrete-shape probes including the issue's
message-typed-`oneof`.
## Semver note
`cargo semver-checks` flags one lint: `message` gains a generic type
parameter (classified major). The formal break surface is explicit
turbofish on a method that previously had no generic parameters — code
that cannot meaningfully exist against 0.8.0. Weighed against the real
regression (the streaming client being unusable in `Send` tasks), this
ships as **0.8.1**.
Signed-off-by: Iain McGinniss <309153+iainmcgin@users.noreply.github.com>1 parent ed5d957 commit fb64539
3 files changed
Lines changed: 46 additions & 8 deletions
File tree
- .changes/unreleased
- connectrpc/src/client
- tests/streaming/src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2401 | 2401 | | |
2402 | 2402 | | |
2403 | 2403 | | |
2404 | | - | |
2405 | | - | |
2406 | | - | |
| 2404 | + | |
2407 | 2405 | | |
2408 | | - | |
| 2406 | + | |
| 2407 | + | |
| 2408 | + | |
| 2409 | + | |
| 2410 | + | |
| 2411 | + | |
| 2412 | + | |
2409 | 2413 | | |
2410 | 2414 | | |
2411 | 2415 | | |
| |||
3139 | 3143 | | |
3140 | 3144 | | |
3141 | 3145 | | |
3142 | | - | |
3143 | | - | |
3144 | | - | |
| 3146 | + | |
3145 | 3147 | | |
3146 | | - | |
| 3148 | + | |
| 3149 | + | |
| 3150 | + | |
| 3151 | + | |
3147 | 3152 | | |
3148 | 3153 | | |
3149 | 3154 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
24 | 51 | | |
25 | 52 | | |
26 | 53 | | |
| |||
0 commit comments