diff options
Diffstat (limited to 'tests/ui/async-await/track-caller')
7 files changed, 195 insertions, 0 deletions
diff --git a/tests/ui/async-await/track-caller/async-block.rs b/tests/ui/async-await/track-caller/async-block.rs new file mode 100644 index 000000000..8e81387c3 --- /dev/null +++ b/tests/ui/async-await/track-caller/async-block.rs @@ -0,0 +1,9 @@ +// edition:2021 + +#![feature(closure_track_caller, stmt_expr_attributes)] + +fn main() { + let _ = #[track_caller] async { + //~^ ERROR attribute should be applied to a function definition [E0739] + }; +} diff --git a/tests/ui/async-await/track-caller/async-block.stderr b/tests/ui/async-await/track-caller/async-block.stderr new file mode 100644 index 000000000..407439921 --- /dev/null +++ b/tests/ui/async-await/track-caller/async-block.stderr @@ -0,0 +1,12 @@ +error[E0739]: attribute should be applied to a function definition + --> $DIR/async-block.rs:6:13 + | +LL | let _ = #[track_caller] async { + | _____________^^^^^^^^^^^^^^^_- +LL | | +LL | | }; + | |_____- not a function definition + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0739`. diff --git a/tests/ui/async-await/track-caller/async-closure-gate.rs b/tests/ui/async-await/track-caller/async-closure-gate.rs new file mode 100644 index 000000000..d9d556855 --- /dev/null +++ b/tests/ui/async-await/track-caller/async-closure-gate.rs @@ -0,0 +1,9 @@ +// edition:2021 + +#![feature(async_closure, stmt_expr_attributes)] + +fn main() { + let _ = #[track_caller] async || { + //~^ ERROR `#[track_caller]` on closures is currently unstable [E0658] + }; +} diff --git a/tests/ui/async-await/track-caller/async-closure-gate.stderr b/tests/ui/async-await/track-caller/async-closure-gate.stderr new file mode 100644 index 000000000..498f1b43b --- /dev/null +++ b/tests/ui/async-await/track-caller/async-closure-gate.stderr @@ -0,0 +1,12 @@ +error[E0658]: `#[track_caller]` on closures is currently unstable + --> $DIR/async-closure-gate.rs:6:13 + | +LL | let _ = #[track_caller] async || { + | ^^^^^^^^^^^^^^^ + | + = note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information + = help: add `#![feature(closure_track_caller)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/async-await/track-caller/issue-105134.rs b/tests/ui/async-await/track-caller/issue-105134.rs new file mode 100644 index 000000000..4e52b8e25 --- /dev/null +++ b/tests/ui/async-await/track-caller/issue-105134.rs @@ -0,0 +1,11 @@ +// check-pass +// edition:2021 + +#[track_caller] +fn f() { + let _ = async {}; +} + +fn main() { + f(); +} diff --git a/tests/ui/async-await/track-caller/panic-track-caller.nofeat.stderr b/tests/ui/async-await/track-caller/panic-track-caller.nofeat.stderr new file mode 100644 index 000000000..51ea225f4 --- /dev/null +++ b/tests/ui/async-await/track-caller/panic-track-caller.nofeat.stderr @@ -0,0 +1,29 @@ +warning: `#[track_caller]` on async functions is a no-op + --> $DIR/panic-track-caller.rs:50:1 + | +LL | #[track_caller] + | ^^^^^^^^^^^^^^^ +LL | / async fn bar_track_caller() { +LL | | panic!() +LL | | } + | |_- this function will not propagate the caller location + | + = note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information + = help: add `#![feature(closure_track_caller)]` to the crate attributes to enable + = note: `#[warn(ungated_async_fn_track_caller)]` on by default + +warning: `#[track_caller]` on async functions is a no-op + --> $DIR/panic-track-caller.rs:62:5 + | +LL | #[track_caller] + | ^^^^^^^^^^^^^^^ +LL | / async fn bar_assoc() { +LL | | panic!(); +LL | | } + | |_____- this function will not propagate the caller location + | + = note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information + = help: add `#![feature(closure_track_caller)]` to the crate attributes to enable + +warning: 2 warnings emitted + diff --git a/tests/ui/async-await/track-caller/panic-track-caller.rs b/tests/ui/async-await/track-caller/panic-track-caller.rs new file mode 100644 index 000000000..f45243b0e --- /dev/null +++ b/tests/ui/async-await/track-caller/panic-track-caller.rs @@ -0,0 +1,113 @@ +// run-pass +// edition:2021 +// revisions: feat nofeat +// needs-unwind +#![feature(async_closure, stmt_expr_attributes)] +#![cfg_attr(feat, feature(closure_track_caller))] + +use std::future::Future; +use std::panic; +use std::sync::{Arc, Mutex}; +use std::task::{Context, Poll, Wake}; +use std::thread::{self, Thread}; + +/// A waker that wakes up the current thread when called. +struct ThreadWaker(Thread); + +impl Wake for ThreadWaker { + fn wake(self: Arc<Self>) { + self.0.unpark(); + } +} + +/// Run a future to completion on the current thread. +fn block_on<T>(fut: impl Future<Output = T>) -> T { + // Pin the future so it can be polled. + let mut fut = Box::pin(fut); + + // Create a new context to be passed to the future. + let t = thread::current(); + let waker = Arc::new(ThreadWaker(t)).into(); + let mut cx = Context::from_waker(&waker); + + // Run the future to completion. + loop { + match fut.as_mut().poll(&mut cx) { + Poll::Ready(res) => return res, + Poll::Pending => thread::park(), + } + } +} + +async fn bar() { + panic!() +} + +async fn foo() { + bar().await +} + +#[track_caller] //[nofeat]~ WARN `#[track_caller]` on async functions is a no-op +async fn bar_track_caller() { + panic!() +} + +async fn foo_track_caller() { + bar_track_caller().await +} + +struct Foo; + +impl Foo { + #[track_caller] //[nofeat]~ WARN `#[track_caller]` on async functions is a no-op + async fn bar_assoc() { + panic!(); + } +} + +async fn foo_assoc() { + Foo::bar_assoc().await +} + +// Since compilation is expected to fail for this fn when using +// `nofeat`, we test that separately in `async-closure-gate.rs` +#[cfg(feat)] +async fn foo_closure() { + let c = #[track_caller] async || { + panic!(); + }; + c().await +} + +fn panicked_at(f: impl FnOnce() + panic::UnwindSafe) -> u32 { + let loc = Arc::new(Mutex::new(None)); + + let hook = panic::take_hook(); + { + let loc = loc.clone(); + panic::set_hook(Box::new(move |info| { + *loc.lock().unwrap() = info.location().map(|loc| loc.line()) + })); + } + panic::catch_unwind(f).unwrap_err(); + panic::set_hook(hook); + let x = loc.lock().unwrap().unwrap(); + x +} + +fn main() { + assert_eq!(panicked_at(|| block_on(foo())), 43); + + #[cfg(feat)] + assert_eq!(panicked_at(|| block_on(foo_track_caller())), 56); + #[cfg(nofeat)] + assert_eq!(panicked_at(|| block_on(foo_track_caller())), 52); + + #[cfg(feat)] + assert_eq!(panicked_at(|| block_on(foo_assoc())), 69); + #[cfg(nofeat)] + assert_eq!(panicked_at(|| block_on(foo_assoc())), 64); + + #[cfg(feat)] + assert_eq!(panicked_at(|| block_on(foo_closure())), 79); +} |