Actually use the right closure kind when checking async Fn goals

This commit is contained in:
Michael Goulet 2024-02-26 01:36:08 +00:00
parent 6bdb8a4a96
commit ff07f55db5
3 changed files with 33 additions and 7 deletions

View File

@ -934,7 +934,8 @@ fn confirm_async_closure_candidate(
(trait_ref, Ty::from_closure_kind(tcx, ty::ClosureKind::Fn)) (trait_ref, Ty::from_closure_kind(tcx, ty::ClosureKind::Fn))
} }
ty::Closure(_, args) => { ty::Closure(_, args) => {
let sig = args.as_closure().sig(); let args = args.as_closure();
let sig = args.sig();
let trait_ref = sig.map_bound(|sig| { let trait_ref = sig.map_bound(|sig| {
ty::TraitRef::new( ty::TraitRef::new(
self.tcx(), self.tcx(),
@ -950,7 +951,7 @@ fn confirm_async_closure_candidate(
ty::TraitRef::new(tcx, future_trait_def_id, [sig.output()]) ty::TraitRef::new(tcx, future_trait_def_id, [sig.output()])
}), }),
)); ));
(trait_ref, Ty::from_closure_kind(tcx, ty::ClosureKind::Fn)) (trait_ref, args.kind_ty())
} }
_ => bug!("expected callable type for AsyncFn candidate"), _ => bug!("expected callable type for AsyncFn candidate"),
}; };

View File

@ -1,7 +1,5 @@
//@ edition:2021 //@ edition:2021
// FIXME(async_closures): This needs a better error message!
#![feature(async_closure)] #![feature(async_closure)]
fn main() { fn main() {
@ -12,4 +10,10 @@ fn needs_async_fn(_: impl async Fn()) {}
//~^ ERROR expected a closure that implements the `async Fn` trait, but this closure only implements `async FnMut` //~^ ERROR expected a closure that implements the `async Fn` trait, but this closure only implements `async FnMut`
x += 1; x += 1;
}); });
let x = String::new();
needs_async_fn(move || async move {
//~^ ERROR expected a closure that implements the `async Fn` trait, but this closure only implements `async FnOnce`
println!("{x}");
});
} }

View File

@ -1,5 +1,5 @@
error[E0525]: expected a closure that implements the `async Fn` trait, but this closure only implements `async FnMut` error[E0525]: expected a closure that implements the `async Fn` trait, but this closure only implements `async FnMut`
--> $DIR/wrong-fn-kind.rs:11:20 --> $DIR/wrong-fn-kind.rs:9:20
| |
LL | needs_async_fn(async || { LL | needs_async_fn(async || {
| -------------- -^^^^^^^ | -------------- -^^^^^^^
@ -14,11 +14,32 @@ LL | | });
| |_____- the requirement to implement `async Fn` derives from here | |_____- the requirement to implement `async Fn` derives from here
| |
note: required by a bound in `needs_async_fn` note: required by a bound in `needs_async_fn`
--> $DIR/wrong-fn-kind.rs:8:31 --> $DIR/wrong-fn-kind.rs:6:31
| |
LL | fn needs_async_fn(_: impl async Fn()) {} LL | fn needs_async_fn(_: impl async Fn()) {}
| ^^^^^^^^^^ required by this bound in `needs_async_fn` | ^^^^^^^^^^ required by this bound in `needs_async_fn`
error: aborting due to 1 previous error error[E0525]: expected a closure that implements the `async Fn` trait, but this closure only implements `async FnOnce`
--> $DIR/wrong-fn-kind.rs:15:20
|
LL | needs_async_fn(move || async move {
| -------------- -^^^^^^
| | |
| _____|______________this closure implements `async FnOnce`, not `async Fn`
| | |
| | required by a bound introduced by this call
LL | |
LL | | println!("{x}");
| | - closure is `async FnOnce` because it moves the variable `x` out of its environment
LL | | });
| |_____- the requirement to implement `async Fn` derives from here
|
note: required by a bound in `needs_async_fn`
--> $DIR/wrong-fn-kind.rs:6:31
|
LL | fn needs_async_fn(_: impl async Fn()) {}
| ^^^^^^^^^^ required by this bound in `needs_async_fn`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0525`. For more information about this error, try `rustc --explain E0525`.