-
Notifications
You must be signed in to change notification settings - Fork 42
Open
Labels
help wantedExtra attention is neededExtra attention is needed
Description
There appears to be some invariance introduced by the IntoConcurrentStream
and Map
implementation that confuses the compiler for the Send
and Sync
autotraits
The following:
use futures_concurrency::concurrent_stream::{ConcurrentStream, IntoConcurrentStream};
fn assert_value_send_sync<T: Send + Sync>(_v: &T) {}
async fn iterative_method(context: &str) -> Vec<String> {
let vec: Vec<u32> = Vec::new();
let mut acc = Vec::new();
for item in vec {
acc.push(handle_item(&item, &context).await);
}
acc
}
async fn concurrent_method(context: &str) -> Vec<String> {
let vec: Vec<u32> = Vec::new();
vec.into_co_stream()
.map(|d| async move { handle_item(&d, &*context).await })
.collect()
.await
}
async fn handle_item(item: &u32, context: &str) -> String {
format!("{context}: {item}")
}
fn main() {
let context = String::new();
let iterative = async {
iterative_method(&context).await;
};
assert_value_send_sync(&iterative);
let concurrent = async {
concurrent_method(&context).await;
};
assert_value_send_sync(&concurrent);
}
fails with the error:
rror[E0308]: mismatched types
--> src/main.rs:36:5
|
17 | .map(|d| async move { handle_item(&d, &*context).await })
| ----------
| |
| the expected `async` block
| the found `async` block
...
36 | assert_value_send_sync(&concurrent);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected `async` block `{async block@src/main.rs:17:18: 17:28}`
found `async` block `{async block@src/main.rs:17:18: 17:28}`
= note: no two async blocks, even if identical, have the same type
= help: consider pinning your async block and casting it to a trait object
note: the lifetime requirement is introduced here
--> src/main.rs:3:30
|
3 | fn assert_value_send_sync<T: Send + Sync>(_v: &T) {}
| ^^^^
error[E0308]: mismatched types
--> src/main.rs:36:5
|
17 | .map(|d| async move { handle_item(&d, &*context).await })
| ----------
| |
| the expected `async` block
| the found `async` block
...
36 | assert_value_send_sync(&concurrent);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected `async` block `{async block@src/main.rs:17:18: 17:28}`
found `async` block `{async block@src/main.rs:17:18: 17:28}`
= note: no two async blocks, even if identical, have the same type
= help: consider pinning your async block and casting it to a trait object
note: the lifetime requirement is introduced here
--> src/main.rs:3:37
|
3 | fn assert_value_send_sync<T: Send + Sync>(_v: &T) {}
| ^^^^
For more information about this error, try `rustc --explain E0308`.
error: could not compile `future-concurrency-repro` (bin "future-concurrency-repro") due to 2 previous errors
I can't make a minimal reproducer, but I first encountered this error message, which I think it's the same issue. To me this suggests this might even be a bug in rustc
. Even if it isn't a bug, the error message makes no sense and should be fixed.
error: implementation of `Send` is not general enough
--> src/main.rs:348:34
|
348 | .route("/dashboard/:id", post(dashboard_post))
| ^^^^^^^^^^^^^^^^^^^^ implementation of `Send` is not general enough
|
= note: `Send` would have to be implemented for the type `&str`
= note: ...but `Send` is actually implemented for the type `&'0 str`, for some specific lifetime `'0`
Metadata
Metadata
Assignees
Labels
help wantedExtra attention is neededExtra attention is needed