-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Async function leads to a "more general type" error #71723
Comments
Workaround: Moving the code creating the boxed stream to its own function also makes the code compile. use futures::{
future::ready,
stream::{empty, iter},
Stream, StreamExt,
};
use std::pin::Pin;
fn is_send<T: Send>(_: T) {}
pub fn test() {
let _ = is_send(make_future_2());
}
async fn make_future_2() {
iter(Some(make_stream()))
.map(|_| empty::<()>())
.flatten()
.for_each(|_| ready(()))
.await
}
fn make_stream() -> impl Stream<Item = ()> {
let s = empty::<()>();
Box::pin(s) as Pin<Box<dyn Stream<Item = ()> + Send + 'static>>
} |
#71671 Because I like link |
@rustbot claim I will attempt to investigate. |
I'm also encountering this in my project. I've spent the last two days trying all sorts of combinations to figure out what was going on to no avail. Then I found this issue. Thank you @stephaneyfx for the workaround. I guess I need to ditch async/await for this particular function. Also note: having the function return |
Did a bit of digging around. I didn't quite figure out what's going on yet, but a few notes: First, removing either of these calls makes the error go away .map(|_| empty::<()>())
.flatten() I'm feeling a bit confused about the types that I'm getting out right now. It looks like the error is somehow coming up around the "lifetime bound" that we get on the |
I'm not sure about the others, but I haven't gotten around to it, so you working on it is fine with me! |
Okay, then I'm assigning myself to this problem. If anyone is working on this I will unassign myself @rustbot claim |
@rustbot claim |
Current output:
|
I was not able to reproduce the original errors, but this (somewhat minimized) test does reproduce: use futures::{
future::ready,
stream::{empty, iter},
Stream, StreamExt,
};
use std::pin::Pin;
fn is_send<T: Send>(_: T) {}
pub fn test() {
let _ = is_send(make_future_2());
}
// Same as make_future, just async
async fn make_future_2() {
iter(Some({
let s = empty::<()>();
Box::pin(s) as Pin<Box<dyn Stream<Item = ()> + Send + 'static>>
}))
.map(|_| empty::<()>())
.flatten()
.for_each(|_| ready(()))
.await
}
fn main() {} I get the following error now:
|
with
|
Another reproduction: use futures::FutureExt; // 0.3.17
use std::future::Future;
fn foo() -> impl Future<Output = ()> + Send + Sync + 'static {
async move {
let work1 = async { "bang" };
let work1 = work1.map(drop);
let _error1 = futures::join!(work1);
}
}
|
This has bitten me a few times, so I sat down and tried to work on this. I think I've written an (at least partial) solution towards this issue. I'll put up a (WIP) PR tomorrow or so, so people can take a look at the implementation. cc: @nikomatsakis, who owns this issue currently |
Just pointing this out, #75791 which was closed as a duplicate of this bug provides a much more straightforward example that doesn't involve async In case that helps someone with this issue. |
This tweaks the Agora context type we use in order to avoid a recurring Rust compiler bug (rust-lang/rust#71723) which makes it suddenly impossible to carry the context across an await. This comes at the cost of increasing String allocations. Though the use of snmalloc mitigates this cost somewhat.
This tweaks the Agora context type we use in order to avoid a recurring Rust compiler bug (rust-lang/rust#71723) which makes it suddenly impossible to carry the context across an await. This comes at the cost of increasing String allocations. Though the use of snmalloc mitigates this cost somewhat.
This tweaks the Agora context type we use in order to avoid a recurring Rust compiler bug (rust-lang/rust#71723) which makes it suddenly impossible to carry the context across an await. This comes at the cost of increasing String allocations. Though the use of snmalloc mitigates this cost somewhat.
Rustc complains about a type being more general than the other when testing if the
Future
returned by anasync
function isSend
. The same code withoutasync
sugar is accepted by the compiler.This might be related to #60658.
I tried to minimize further, but removing
.flatten()
, the boxing with a trait object or even the mapping to an empty stream makes the code compile.Playground
Expected result
It compiles successfully --
is_send(make_future())
andis_send(make_future_2())
are both accepted by the compiler.Actual result
is_send(make_future_2())
is rejected with the following error:The text was updated successfully, but these errors were encountered: