makepad/libs/relax/compiler/tests/async_closure_ref_output.rs
Admin cd658a30ef makepad run / Relax: solver and typeck fixes
- async closure Output deduction, solver cycle step kinds from the goal source,
  object supertrait projections, impl candidate merging, trait supertrait
  well-formedness, E0282 for casts and method calls on diverging variables,
  the (..) tuple pattern

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 07:46:04 +02:00

32 lines
1 KiB
Rust

// An `AsyncFn(&str) -> &str` bound gives the async closure's body its return type with the
// closure's own late-bound region (rustc coroutine-closure `return_ty`); the closure must be
// accepted and run.
use std::future::Future;
use std::pin::pin;
use std::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
fn noop_raw() -> RawWaker {
fn clone(_: *const ()) -> RawWaker { noop_raw() }
fn noop(_: *const ()) {}
static VT: RawWakerVTable = RawWakerVTable::new(clone, noop, noop, noop);
RawWaker::new(std::ptr::null(), &VT)
}
fn block_on<F: Future>(f: F) -> F::Output {
let waker = unsafe { Waker::from_raw(noop_raw()) };
let mut cx = Context::from_waker(&waker);
let mut f = pin!(f);
loop {
if let Poll::Ready(v) = f.as_mut().poll(&mut cx) { return v; }
}
}
async fn call(f: impl AsyncFn(&str) -> &str) -> usize {
f("hello").await.len()
}
#[test]
fn ref_output() {
assert_eq!(block_on(call(async |x| x)), 5);
assert_eq!(block_on(call(async |x: &str| { let y = x; y })), 5);
}