-
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 closure parameter type inference does not work anymore #127425
Comments
We don't typically mark nightly features with Are you certain this regressed in 1.80? This should have regressed in #120361, when I reimplemented async closures completely. |
I am not 100% sure when it happened. I used to work with 1.7x a couple of months ago. Then I left my project for a moment. When I came back, after updating to 1.81 it no longer works. IIRC before leaving it was around 1.79, but I'm not sure. |
This limitation to async closure signature inference has to do with the fact that the combinators you're using (e.g. |
I posted a minimal example, indeed async does not make much sense here, but in project I work on it does. As a workaround I've just annotated parameters with original types, but I still believe this is a bug. |
Rollup merge of rust-lang#127482 - compiler-errors:closure-two-par-sig-inference, r=oli-obk Infer async closure signature from (old-style) two-part `Fn` + `Future` bounds When an async closure is passed to a function that has a "two-part" `Fn` and `Future` trait bound, like: ```rust use std::future::Future; fn not_exactly_an_async_closure(_f: F) where F: FnOnce(String) -> Fut, Fut: Future<Output = ()>, {} ``` The we want to be able to extract the signature to guide inference in the async closure, like: ```rust not_exactly_an_async_closure(async |string| { for x in string.split('\n') { ... } //~^ We need to know that the type of `string` is `String` to call methods on it. }) ``` Closure signature inference will see two bounds: `<?F as FnOnce<Args>>::Output = ?Fut`, `<?Fut as Future>::Output = String`. We need to extract the signature by looking through both projections. ### Why? I expect the ecosystem's move onto `async Fn` trait bounds (which are not affected by this PR, and already do signature inference fine) to be slow. In the mean time, I don't see major overhead to supporting this "old–style" of trait bounds that were used to model async closures. r? oli-obk Fixes rust-lang#127468 Fixes rust-lang#127425
While the problem from first message in issue seems to be fixed, there are still cases when this fails. One of examples is when using #![feature(async_closure)]
use anyhow::Error;
use futures::{stream::repeat_with, StreamExt, TryStreamExt};
fn accept_str(_: &str) {}
fn accept_string(_: &String) {}
#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<(), Error> {
repeat_with(|| "foo".to_owned())
.take(1)
.map(Result::<_, Error>::Ok)
.try_for_each(async move |value| {
// error on whole closure, rust thinks that type of value is `str`
accept_str(&value);
// type annotations needed, cannot infer type
accept_str(value.as_str());
// this works
accept_string(&value); // ok
Ok(())
})
.await?;
Ok(())
} Should I open new issue, or this one will be reopened? |
Please open a new issue, since it's likely a different root cause |
When using async closures, rust since around 1.80 fails to infer parameter type in most scenarios.
I expected to see this happen: All options used to work in past versions of rust
Instead, this happened: Without explicit type hint it fails
Version it worked on
It used to work in the past, around 1.79
Version with regression
The text was updated successfully, but these errors were encountered: