Skip to content

Commit 75b557a

Browse files
committed
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.
1 parent 9eee230 commit 75b557a

File tree

4 files changed

+65
-1
lines changed

4 files changed

+65
-1
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
362362
continue;
363363
}
364364

365-
let is_closure = matches!(arg.kind, ExprKind::Closure { .. });
365+
// For this check, we do *not* want to treat async generator closures (async blocks)
366+
// as proper closures. Doing so would regress type inference when feeding
367+
// the return value of an argument-position async block to an argument-position
368+
// closure wrapped in a block.
369+
// See <https://github.com/rust-lang/rust/issues/112225>.
370+
let is_closure = if let ExprKind::Closure(closure) = arg.kind {
371+
!tcx.generator_is_async(closure.def_id.to_def_id())
372+
} else {
373+
false
374+
};
366375
if is_closure != check_closures {
367376
continue;
368377
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// check-pass
2+
// edition:2021
3+
4+
use core::future::Future;
5+
6+
fn main() {
7+
do_async(async { (0,) }, {
8+
// closure must be inside block
9+
|info| println!("{:?}", info.0)
10+
});
11+
}
12+
13+
fn do_async<R, Fut, F>(_tokio_fut: Fut, _glib_closure: F)
14+
where
15+
Fut: Future<Output = R>,
16+
F: FnOnce(R),
17+
{
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// edition:2021
2+
3+
// With the current compiler logic, we cannot have both the `112225-1` case,
4+
// and this `112225-2` case working, as the type inference depends on the evaluation
5+
// order, and there is some explicit ordering going on.
6+
// See the `check_closures` part in `FnCtxt::check_argument_types`.
7+
// The `112225-1` case was a regression in real world code, whereas the `112225-2`
8+
// case never used to work prior to 1.70.
9+
10+
use core::future::Future;
11+
12+
fn main() {
13+
let x = Default::default();
14+
//~^ ERROR: type annotations needed
15+
do_async(
16+
async { x.0; },
17+
{ || { let _: &(i32,) = &x; } },
18+
);
19+
}
20+
fn do_async<Fut, T>(_fut: Fut, _val: T, ) {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0282]: type annotations needed
2+
--> $DIR/issue-112225-2.rs:13:9
3+
|
4+
LL | let x = Default::default();
5+
| ^
6+
...
7+
LL | async { x.0; },
8+
| - type must be known at this point
9+
|
10+
help: consider giving `x` an explicit type
11+
|
12+
LL | let x: /* Type */ = Default::default();
13+
| ++++++++++++
14+
15+
error: aborting due to previous error
16+
17+
For more information about this error, try `rustc --explain E0282`.

0 commit comments

Comments
 (0)