Open keithmss opened 3 years ago
Reduced some (but it'd be nice to remove the futures
dependency):
use futures::stream;
use futures::stream::StreamExt;
use std::future;
struct Bar {}
impl Bar {
async fn get_foo<'a>(&self) -> Vec<Foo<'a>> {
let results = vec![()];
let foo: Vec<Foo<'a>> = stream::iter(results)
.filter_map(|_| async move { Some(Foo::new()) })
.filter(|m| future::ready(true))
.collect()
.await;
foo
}
}
struct Foo<'a> {
_use_a: &'a (),
}
impl<'a> Foo<'a> {
fn new() -> Foo<'a> {
Foo { _use_a: &() }
}
}
fn demand_is_send<T>(t: T)
where
T: Send,
{
}
fn main() {
let bar = Bar {};
demand_is_send(async move { bar.get_foo().await })
}
@rustbot label A-async-await A-diagnostics
The T: Generator<ResumeTy>
error is gone on nightly (bisected to #73905) but the confusing type mismatch error remains
Further minimized for the remaining error.. playground
use futures::stream;
use futures::stream::StreamExt;
use std::future::{self, Future};
fn get_foo<'a>() -> impl Future<Output = Vec<()>> + 'a {
async {
let results = vec![()];
let foo: Vec<()> = stream::iter(results)
.filter_map(|_| async move { Some(()) })
.filter(|m| future::ready(true))
.collect()
.await;
foo
}
}
fn demand_is_send<T>(t: T)
where T: Send
{}
fn main() {
demand_is_send(get_foo())
}
Haven't tried removing the futures dep yet.
I think I came across the same issue, but with a slightly different snippet of code:
use futures::future::{join, ready, Future};
use futures::stream::{self, StreamExt};
fn f() -> impl Future<Output = ()> + Send {
async {
let a = &();
join(
stream::empty().for_each(|_: ()| async { drop(a) }),
ready(()),
)
.await;
}
}
error[E0308]: mismatched types
--> src/lib.rs:4:11
|
4 | fn f() -> impl Future<Output = ()> + Send {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
...
8 | stream::empty().for_each(|_: ()| async { drop(a) }),
| -----------
| |
| the expected generator
| the found generator
|
= note: expected opaque type `impl futures::Future`
found opaque type `impl futures::Future`
When compiling on stable, I'm also getting the error about T: Generator<ResumeTy>
.
Curiously, the usage of join
(or the join!
macro) seems necessary to trigger the error message in this case, as just awaiting the future directly compiles just fine.
One-crate repro: (playground)
use std::future::Future;
use std::marker::PhantomData;
trait Stream {
type Item;
}
struct Filter<St: Stream> {
pending_item: St::Item,
}
fn filter<St: Stream>(_: St) -> Filter<St> {
unimplemented!();
}
struct FilterMap<Fut, F> {
f: F,
pending: PhantomData<Fut>,
}
impl<Fut, F> Stream for FilterMap<Fut, F>
where
F: FnMut() -> Fut,
Fut: Future,
{
type Item = ();
}
pub fn get_foo() -> impl Future + Send {
async {
let _y = &();
let _x = filter(FilterMap {
f: || async move { *_y },
pending: PhantomData,
});
async {}.await;
}
}
This and #71723 look like the same thing.
Is there any progress or workaround for this?
Triage: current output (the bound being pointed at is new):
error[E0308]: mismatched types
--> src/main.rs:20:5
|
9 | .filter_map(|_| async move { Some(()) })
| ------------
| |
| the expected `async` block
| the found `async` block
...
20 | demand_is_send(get_foo())
| ^^^^^^^^^^^^^^ lifetime mismatch
|
= note: expected opaque type `impl futures::Future`
found opaque type `impl futures::Future`
note: the lifetime requirement is introduced here
--> src/main.rs:17:14
|
17 | where T: Send
| ^^^^
Triage: Current output (fallout from NLL stabilization):
error: higher-ranked lifetime error
--> src/main.rs:20:5
|
20 | demand_is_send(get_foo())
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: could not prove for<'r, 's> impl futures::Future<Output = Vec<()>>: std::marker::Send
Current output:
error[E0308]: mismatched types
--> src/main.rs:20:5
|
9 | .filter_map(|_| async move { Some(()) })
| -----------------------
| |
| the expected `async` block
| the found `async` block
...
20 | demand_is_send(get_foo())
| ^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected `async` block `{async block@src/main.rs:9:29: 9:52}`
found `async` block `{async block@src/main.rs:9:29: 9:52}`
note: the lifetime requirement is introduced here
--> src/main.rs:17:14
|
17 | where T: Send
| ^^^^
error message
Hello! This is a bug report for a confusing/bad error message:
code
I apologize that the following probably isn't the easiest way to trigger it. I am relatively new to Rust and am just now working with Generics and Lifetimes now which is how I got here. The following is a very stripped down version of my code (it compiles without the commented line).
main.rs
:Meta
rustc --version --verbose
:Cargo.toml
:This is my first bug report for a project of this size. Please let me know if you need me to modify anything. Thank you!