summaryrefslogtreecommitdiffstats
path: root/tests/ui/async-await/track-caller
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/async-await/track-caller')
-rw-r--r--tests/ui/async-await/track-caller/async-block.rs9
-rw-r--r--tests/ui/async-await/track-caller/async-block.stderr12
-rw-r--r--tests/ui/async-await/track-caller/async-closure-gate.rs9
-rw-r--r--tests/ui/async-await/track-caller/async-closure-gate.stderr12
-rw-r--r--tests/ui/async-await/track-caller/issue-105134.rs11
-rw-r--r--tests/ui/async-await/track-caller/panic-track-caller.nofeat.stderr29
-rw-r--r--tests/ui/async-await/track-caller/panic-track-caller.rs113
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);
+}