3 // revisions: feat nofeat
5 #![feature(async_closure, stmt_expr_attributes)]
6 #![cfg_attr(feat, feature(closure_track_caller))]
8 use std::future::Future;
10 use std::sync::{Arc, Mutex};
11 use std::task::{Context, Poll, Wake};
12 use std::thread::{self, Thread};
14 /// A waker that wakes up the current thread when called.
15 struct ThreadWaker(Thread);
17 impl Wake for ThreadWaker {
18 fn wake(self: Arc<Self>) {
23 /// Run a future to completion on the current thread.
24 fn block_on<T>(fut: impl Future<Output = T>) -> T {
25 // Pin the future so it can be polled.
26 let mut fut = Box::pin(fut);
28 // Create a new context to be passed to the future.
29 let t = thread::current();
30 let waker = Arc::new(ThreadWaker(t)).into();
31 let mut cx = Context::from_waker(&waker);
33 // Run the future to completion.
35 match fut.as_mut().poll(&mut cx) {
36 Poll::Ready(res) => return res,
37 Poll::Pending => thread::park(),
50 #[track_caller] //[nofeat]~ WARN `#[track_caller]` on async functions is a no-op
51 async fn bar_track_caller() {
55 async fn foo_track_caller() {
56 bar_track_caller().await
62 #[track_caller] //[nofeat]~ WARN `#[track_caller]` on async functions is a no-op
63 async fn bar_assoc() {
68 async fn foo_assoc() {
69 Foo::bar_assoc().await
72 // Since compilation is expected to fail for this fn when using
73 // `nofeat`, we test that separately in `async-closure-gate.rs`
75 async fn foo_closure() {
76 let c = #[track_caller] async || {
82 fn panicked_at(f: impl FnOnce() + panic::UnwindSafe) -> u32 {
83 let loc = Arc::new(Mutex::new(None));
85 let hook = panic::take_hook();
87 let loc = loc.clone();
88 panic::set_hook(Box::new(move |info| {
89 *loc.lock().unwrap() = info.location().map(|loc| loc.line())
92 panic::catch_unwind(f).unwrap_err();
93 panic::set_hook(hook);
94 let x = loc.lock().unwrap().unwrap();
99 assert_eq!(panicked_at(|| block_on(foo())), 43);
102 assert_eq!(panicked_at(|| block_on(foo_track_caller())), 56);
104 assert_eq!(panicked_at(|| block_on(foo_track_caller())), 52);
107 assert_eq!(panicked_at(|| block_on(foo_assoc())), 69);
109 assert_eq!(panicked_at(|| block_on(foo_assoc())), 64);
112 assert_eq!(panicked_at(|| block_on(foo_closure())), 79);