diff options
| author | Michael Goulet <michael@errs.io> | 2024-02-26 22:53:45 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2024-02-27 17:21:40 +0000 |
| commit | 2252ff730285decb81837db51a922608b2f036cc (patch) | |
| tree | f528f51734d1806b3ef45e7791545d6b7c4a6f01 | |
| parent | 4c0016a01f15d207ae1a430fd601098289654bb9 (diff) | |
| download | rust-2252ff730285decb81837db51a922608b2f036cc.tar.gz rust-2252ff730285decb81837db51a922608b2f036cc.zip | |
Also support `fnptr(): async Fn` in codegen
| -rw-r--r-- | compiler/rustc_mir_transform/src/shim.rs | 6 | ||||
| -rw-r--r-- | tests/ui/async-await/async-fn/higher-ranked-async-fn.rs | 31 |
2 files changed, 36 insertions, 1 deletions
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 75613a2c555..733e2f93b25 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -37,7 +37,11 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<' } ty::InstanceDef::FnPtrShim(def_id, ty) => { let trait_ = tcx.trait_of_item(def_id).unwrap(); - let adjustment = match tcx.fn_trait_kind_from_def_id(trait_) { + // Supports `Fn` or `async Fn` traits. + let adjustment = match tcx + .fn_trait_kind_from_def_id(trait_) + .or_else(|| tcx.async_fn_trait_kind_from_def_id(trait_)) + { Some(ty::ClosureKind::FnOnce) => Adjustment::Identity, Some(ty::ClosureKind::Fn) => Adjustment::Deref { source: DerefSource::ImmRef }, Some(ty::ClosureKind::FnMut) => Adjustment::Deref { source: DerefSource::MutRef }, diff --git a/tests/ui/async-await/async-fn/higher-ranked-async-fn.rs b/tests/ui/async-await/async-fn/higher-ranked-async-fn.rs new file mode 100644 index 00000000000..5680c057737 --- /dev/null +++ b/tests/ui/async-await/async-fn/higher-ranked-async-fn.rs @@ -0,0 +1,31 @@ +//@ aux-build:block-on.rs +//@ edition:2018 +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ build-pass (since it ICEs during mono) + +#![feature(async_closure)] + +extern crate block_on; + +use std::future::Future; + +async fn f(arg: &i32) {} + +async fn func<F>(f: F) +where + F: async for<'a> Fn(&'a i32), +{ + let x: i32 = 0; + f(&x).await; +} + +fn main() { + block_on::block_on(async { + // Function + func(f).await; + + // Regular closure (doesn't capture) + func(|x: &i32| async {}); + }); +} |
