mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-31 06:22:00 +00:00
Auto merge of #112266 - Swatinem:fix-async-block-inference, r=compiler-errors
Fix type-inference regression in #112225 The type inference of argument-position closures and async blocks regressed in 1.70 as the evaluation order of async blocks changed, as they are not implicitly wrapped in an identity-function anymore. Fixes #112225 by making sure the evaluation order stays the same as it used to. r? `@compiler-errors` As this was a stable-to-stable regression, it might be worth to consider backporting. Although the workaround for this is trivial as well: Just wrap the async block in another block.
This commit is contained in:
commit
dcf3571c51
@ -362,7 +362,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_closure = matches!(arg.kind, ExprKind::Closure { .. });
|
// For this check, we do *not* want to treat async generator closures (async blocks)
|
||||||
|
// as proper closures. Doing so would regress type inference when feeding
|
||||||
|
// the return value of an argument-position async block to an argument-position
|
||||||
|
// closure wrapped in a block.
|
||||||
|
// See <https://github.com/rust-lang/rust/issues/112225>.
|
||||||
|
let is_closure = if let ExprKind::Closure(closure) = arg.kind {
|
||||||
|
!tcx.generator_is_async(closure.def_id.to_def_id())
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
if is_closure != check_closures {
|
if is_closure != check_closures {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
18
tests/ui/async-await/issues/issue-112225-1.rs
Normal file
18
tests/ui/async-await/issues/issue-112225-1.rs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// check-pass
|
||||||
|
// edition:2021
|
||||||
|
|
||||||
|
use core::future::Future;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
do_async(async { (0,) }, {
|
||||||
|
// closure must be inside block
|
||||||
|
|info| println!("{:?}", info.0)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_async<R, Fut, F>(_tokio_fut: Fut, _glib_closure: F)
|
||||||
|
where
|
||||||
|
Fut: Future<Output = R>,
|
||||||
|
F: FnOnce(R),
|
||||||
|
{
|
||||||
|
}
|
20
tests/ui/async-await/issues/issue-112225-2.rs
Normal file
20
tests/ui/async-await/issues/issue-112225-2.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// edition:2021
|
||||||
|
|
||||||
|
// With the current compiler logic, we cannot have both the `112225-1` case,
|
||||||
|
// and this `112225-2` case working, as the type inference depends on the evaluation
|
||||||
|
// order, and there is some explicit ordering going on.
|
||||||
|
// See the `check_closures` part in `FnCtxt::check_argument_types`.
|
||||||
|
// The `112225-1` case was a regression in real world code, whereas the `112225-2`
|
||||||
|
// case never used to work prior to 1.70.
|
||||||
|
|
||||||
|
use core::future::Future;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = Default::default();
|
||||||
|
//~^ ERROR: type annotations needed
|
||||||
|
do_async(
|
||||||
|
async { x.0; },
|
||||||
|
{ || { let _: &(i32,) = &x; } },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
fn do_async<Fut, T>(_fut: Fut, _val: T, ) {}
|
17
tests/ui/async-await/issues/issue-112225-2.stderr
Normal file
17
tests/ui/async-await/issues/issue-112225-2.stderr
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
error[E0282]: type annotations needed
|
||||||
|
--> $DIR/issue-112225-2.rs:13:9
|
||||||
|
|
|
||||||
|
LL | let x = Default::default();
|
||||||
|
| ^
|
||||||
|
...
|
||||||
|
LL | async { x.0; },
|
||||||
|
| - type must be known at this point
|
||||||
|
|
|
||||||
|
help: consider giving `x` an explicit type
|
||||||
|
|
|
||||||
|
LL | let x: /* Type */ = Default::default();
|
||||||
|
| ++++++++++++
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0282`.
|
Loading…
Reference in New Issue
Block a user