diff --git a/src/tools/miri/tests/pass/async-panic-track-caller.rs b/src/tools/miri/tests/pass/async-panic-track-caller.rs new file mode 100644 index 0000000000000..062e07cffc8b9 --- /dev/null +++ b/src/tools/miri/tests/pass/async-panic-track-caller.rs @@ -0,0 +1,170 @@ +// This test is duplicated (with changes) at +// tests/ui/async-await/track-caller/panic-track-caller.rs + +//@ edition:2021 +//@ revisions: afn cls afn_cls nofeat +//@ run-native +// +// +// +// Padding comment so that the line numbers are the same as panic-track-caller.rs +#![feature(stmt_expr_attributes)] +#![cfg_attr(any(afn, afn_cls), feature(async_fn_track_caller))] +#![cfg_attr(any(cls, afn_cls), feature(closure_track_caller))] +#![allow(unused)] + +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.0.unpark(); + } +} + +/// Run a future to completion on the current thread. +fn block_on(fut: impl Future) -> 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() { + let future = bar(); + future.await; +} + +#[cfg_attr(any(cls, nofeat), expect(ungated_async_fn_track_caller))] +#[track_caller] +async fn bar_track_caller() { + panic!() +} + +async fn foo_track_caller() { + let future = bar_track_caller(); + future.await; +} + +struct Foo; + +impl Foo { + #[cfg_attr(any(cls, nofeat), expect(ungated_async_fn_track_caller))] + #[track_caller] + async fn bar_assoc() { + panic!(); + } +} + +async fn foo_assoc() { + let future = Foo::bar_assoc(); + future.await; +} + +// Since compilation is expected to fail for this fn when `closure_track_caller` +// is disabled, we test that separately in `async-closure-gate.rs` +#[cfg(any(cls, afn_cls))] +async fn foo_closure() { + let closure = #[track_caller] + async || { + panic!(); + }; + let future = closure(); + future.await; +} + +// Since compilation is expected to fail for this fn when `closure_track_caller` +// is disabled, we test that separately in `async-closure-gate.rs` +#[cfg(any(cls, afn_cls))] +async fn foo_block() { + let future = #[track_caller] + async { + panic!(); + }; + future.await; +} + +#[cfg_attr(any(cls, nofeat), expect(ungated_async_fn_track_caller))] +#[track_caller] +async fn bar_manual_poll() { + panic!(); +} + +fn foo_manual_poll() { + let future = bar_manual_poll(); + let future = std::pin::pin!(future); + let mut cx = std::task::Context::from_waker(std::task::Waker::noop()); + let res = future.poll(&mut cx); + assert_eq!(res, std::task::Poll::Ready(())); +} + +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 +} + +// FIXME(async_fn_track_caller): Currently, #[track_caller] on an async function +// uses the location where the future is awaited or polled. +// The correct behavior as per T-lang is to use the location where the function is called. +fn main() { + assert_eq!(panicked_at(|| block_on(foo())), 51); + + #[cfg(any(afn, afn_cls))] + assert_eq!(panicked_at(|| block_on(foo_track_caller())), 67); + #[cfg(any(cls, nofeat))] + assert_eq!(panicked_at(|| block_on(foo_track_caller())), 62); + + #[cfg(any(afn, afn_cls))] + assert_eq!(panicked_at(|| block_on(foo_assoc())), 82); + #[cfg(any(cls, nofeat))] + assert_eq!(panicked_at(|| block_on(foo_assoc())), 76); + + // FIXME(closure_track_caller): if closure_track_caller is enabled, but + // async_fn_track_caller is disabled, then #[track_caller] on async closures + // silently do nothing. Either it should function, or we should emit a warning. + // See #161961 + #[cfg(cls)] + assert_eq!(panicked_at(|| block_on(foo_closure())), 91); + #[cfg(afn_cls)] + assert_eq!(panicked_at(|| block_on(foo_closure())), 94); + + #[cfg(any(cls, afn_cls))] + assert_eq!(panicked_at(|| block_on(foo_block())), 105); + + #[cfg(any(afn, afn_cls))] + assert_eq!(panicked_at(|| foo_manual_poll()), 118); + #[cfg(any(cls, nofeat))] + assert_eq!(panicked_at(|| foo_manual_poll()), 111); +} diff --git a/tests/ui/async-await/track-caller/async-block.afn.stderr b/tests/ui/async-await/track-caller/async-block.afn.stderr index b6a7481a4d119..89ebe2df60609 100644 --- a/tests/ui/async-await/track-caller/async-block.afn.stderr +++ b/tests/ui/async-await/track-caller/async-block.afn.stderr @@ -1,7 +1,7 @@ error[E0658]: `#[track_caller]` on closures is currently unstable - --> $DIR/async-block.rs:8:13 + --> $DIR/async-block.rs:11:13 | -LL | let _ = #[track_caller] async { +LL | let _ = #[track_caller] | ^^^^^^^^^^^^^^^ | = note: see issue #87417 for more information @@ -9,9 +9,9 @@ LL | let _ = #[track_caller] async { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `#[track_caller]` on closures is currently unstable - --> $DIR/async-block.rs:15:13 + --> $DIR/async-block.rs:19:13 | -LL | let _ = #[track_caller] async { +LL | let _ = #[track_caller] | ^^^^^^^^^^^^^^^ | = note: see issue #87417 for more information @@ -19,9 +19,9 @@ LL | let _ = #[track_caller] async { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `#[track_caller]` on closures is currently unstable - --> $DIR/async-block.rs:23:17 + --> $DIR/async-block.rs:28:17 | -LL | let _ = #[track_caller] async { +LL | let _ = #[track_caller] | ^^^^^^^^^^^^^^^ | = note: see issue #87417 for more information diff --git a/tests/ui/async-await/track-caller/async-block.cls.stderr b/tests/ui/async-await/track-caller/async-block.cls.stderr new file mode 100644 index 0000000000000..0e9dbc4afa05f --- /dev/null +++ b/tests/ui/async-await/track-caller/async-block.cls.stderr @@ -0,0 +1,42 @@ +error: `#[track_caller]` on async functions is a no-op + --> $DIR/async-block.rs:16:1 + | +LL | #[track_caller] + | ^^^^^^^^^^^^^^^ +LL | +LL | / async fn foo() { +LL | | let _ = #[track_caller] +LL | | +LL | | async {}; +LL | | } + | |_- this function will not propagate the caller location + | + = note: see issue #110011 for more information + = help: add `#![feature(async_fn_track_caller)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +note: the lint level is defined here + --> $DIR/async-block.rs:6:9 + | +LL | #![deny(ungated_async_fn_track_caller)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `#[track_caller]` on async functions is a no-op + --> $DIR/async-block.rs:24:1 + | +LL | #[track_caller] + | ^^^^^^^^^^^^^^^ +LL | +LL | / async fn foo2() { +LL | | let _ = async { +LL | | let _ = #[track_caller] +... | +LL | | }; +LL | | } + | |_- this function will not propagate the caller location + | + = note: see issue #110011 for more information + = help: add `#![feature(async_fn_track_caller)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 2 previous errors + diff --git a/tests/ui/async-await/track-caller/async-block.nofeat.stderr b/tests/ui/async-await/track-caller/async-block.nofeat.stderr index b6a7481a4d119..89ebe2df60609 100644 --- a/tests/ui/async-await/track-caller/async-block.nofeat.stderr +++ b/tests/ui/async-await/track-caller/async-block.nofeat.stderr @@ -1,7 +1,7 @@ error[E0658]: `#[track_caller]` on closures is currently unstable - --> $DIR/async-block.rs:8:13 + --> $DIR/async-block.rs:11:13 | -LL | let _ = #[track_caller] async { +LL | let _ = #[track_caller] | ^^^^^^^^^^^^^^^ | = note: see issue #87417 for more information @@ -9,9 +9,9 @@ LL | let _ = #[track_caller] async { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `#[track_caller]` on closures is currently unstable - --> $DIR/async-block.rs:15:13 + --> $DIR/async-block.rs:19:13 | -LL | let _ = #[track_caller] async { +LL | let _ = #[track_caller] | ^^^^^^^^^^^^^^^ | = note: see issue #87417 for more information @@ -19,9 +19,9 @@ LL | let _ = #[track_caller] async { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `#[track_caller]` on closures is currently unstable - --> $DIR/async-block.rs:23:17 + --> $DIR/async-block.rs:28:17 | -LL | let _ = #[track_caller] async { +LL | let _ = #[track_caller] | ^^^^^^^^^^^^^^^ | = note: see issue #87417 for more information diff --git a/tests/ui/async-await/track-caller/async-block.rs b/tests/ui/async-await/track-caller/async-block.rs index 900d5ef25504d..f56921c017d12 100644 --- a/tests/ui/async-await/track-caller/async-block.rs +++ b/tests/ui/async-await/track-caller/async-block.rs @@ -1,27 +1,32 @@ //@ edition:2021 -//@ revisions: afn nofeat +//@ revisions: afn cls afn_cls nofeat +//@[afn_cls] check-pass #![feature(stmt_expr_attributes)] -#![cfg_attr(afn, feature(async_fn_track_caller))] +#![deny(ungated_async_fn_track_caller)] +#![cfg_attr(any(afn, afn_cls), feature(async_fn_track_caller))] +#![cfg_attr(any(cls, afn_cls), feature(closure_track_caller))] fn main() { - let _ = #[track_caller] async { - //~^ ERROR `#[track_caller]` on closures is currently unstable [E0658] - }; + let _ = #[track_caller] + //[nofeat,afn]~^ ERROR `#[track_caller]` on closures is currently unstable [E0658] + async {}; } #[track_caller] +//[cls]~^ ERROR `#[track_caller]` on async functions is a no-op async fn foo() { - let _ = #[track_caller] async { - //~^ ERROR `#[track_caller]` on closures is currently unstable [E0658] - }; + let _ = #[track_caller] + //[nofeat,afn]~^ ERROR `#[track_caller]` on closures is currently unstable [E0658] + async {}; } #[track_caller] +//[cls]~^ ERROR `#[track_caller]` on async functions is a no-op async fn foo2() { let _ = async { - let _ = #[track_caller] async { - //~^ ERROR `#[track_caller]` on closures is currently unstable [E0658] - }; + let _ = #[track_caller] + //[nofeat,afn]~^ ERROR `#[track_caller]` on closures is currently unstable [E0658] + async {}; }; } diff --git a/tests/ui/async-await/track-caller/async-closure-gate.afn.stderr b/tests/ui/async-await/track-caller/async-closure-gate.afn.stderr index 6887a904211ec..fb774290bde4e 100644 --- a/tests/ui/async-await/track-caller/async-closure-gate.afn.stderr +++ b/tests/ui/async-await/track-caller/async-closure-gate.afn.stderr @@ -1,7 +1,7 @@ error[E0658]: `#[track_caller]` on closures is currently unstable - --> $DIR/async-closure-gate.rs:8:13 + --> $DIR/async-closure-gate.rs:11:13 | -LL | let _ = #[track_caller] async || { +LL | let _ = #[track_caller] | ^^^^^^^^^^^^^^^ | = note: see issue #87417 for more information @@ -9,9 +9,9 @@ LL | let _ = #[track_caller] async || { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `#[track_caller]` on closures is currently unstable - --> $DIR/async-closure-gate.rs:15:13 + --> $DIR/async-closure-gate.rs:19:13 | -LL | let _ = #[track_caller] async || { +LL | let _ = #[track_caller] | ^^^^^^^^^^^^^^^ | = note: see issue #87417 for more information @@ -19,9 +19,9 @@ LL | let _ = #[track_caller] async || { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `#[track_caller]` on closures is currently unstable - --> $DIR/async-closure-gate.rs:21:13 + --> $DIR/async-closure-gate.rs:25:13 | -LL | let _ = #[track_caller] || { +LL | let _ = #[track_caller] | ^^^^^^^^^^^^^^^ | = note: see issue #87417 for more information @@ -29,9 +29,9 @@ LL | let _ = #[track_caller] || { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `#[track_caller]` on closures is currently unstable - --> $DIR/async-closure-gate.rs:29:17 + --> $DIR/async-closure-gate.rs:32:17 | -LL | let _ = #[track_caller] || { +LL | let _ = #[track_caller] | ^^^^^^^^^^^^^^^ | = note: see issue #87417 for more information @@ -39,9 +39,9 @@ LL | let _ = #[track_caller] || { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `#[track_caller]` on closures is currently unstable - --> $DIR/async-closure-gate.rs:37:9 + --> $DIR/async-closure-gate.rs:40:9 | -LL | #[track_caller] || { +LL | #[track_caller] | ^^^^^^^^^^^^^^^ | = note: see issue #87417 for more information @@ -49,48 +49,15 @@ LL | #[track_caller] || { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `#[track_caller]` on closures is currently unstable - --> $DIR/async-closure-gate.rs:47:13 + --> $DIR/async-closure-gate.rs:49:13 | -LL | #[track_caller] || { +LL | #[track_caller] | ^^^^^^^^^^^^^^^ | = note: see issue #87417 for more information = help: add `#![feature(closure_track_caller)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0308]: mismatched types - --> $DIR/async-closure-gate.rs:27:5 - | -LL | fn foo3() { - | - help: try adding a return type: `-> impl Future` -LL | / async { -LL | | -LL | | let _ = #[track_caller] || { -... | -LL | | } - | |_____^ expected `()`, found `async` block - | - = note: expected unit type `()` - found `async` block `{async block@$DIR/async-closure-gate.rs:27:5: 27:10}` - -error[E0308]: mismatched types - --> $DIR/async-closure-gate.rs:44:5 - | -LL | fn foo5() { - | - help: try adding a return type: `-> impl Future` -LL | / async { -LL | | -LL | | let _ = || { -LL | | #[track_caller] || { -... | -LL | | }; -LL | | } - | |_____^ expected `()`, found `async` block - | - = note: expected unit type `()` - found `async` block `{async block@$DIR/async-closure-gate.rs:44:5: 44:10}` - -error: aborting due to 8 previous errors +error: aborting due to 6 previous errors -Some errors have detailed explanations: E0308, E0658. -For more information about an error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/async-await/track-caller/async-closure-gate.cls.stderr b/tests/ui/async-await/track-caller/async-closure-gate.cls.stderr new file mode 100644 index 0000000000000..5fe7a2fb7d36a --- /dev/null +++ b/tests/ui/async-await/track-caller/async-closure-gate.cls.stderr @@ -0,0 +1,24 @@ +error: `#[track_caller]` on async functions is a no-op + --> $DIR/async-closure-gate.rs:16:1 + | +LL | #[track_caller] + | ^^^^^^^^^^^^^^^ +LL | +LL | / async fn foo() { +LL | | let _ = #[track_caller] +LL | | +LL | | async || {}; +LL | | } + | |_- this function will not propagate the caller location + | + = note: see issue #110011 for more information + = help: add `#![feature(async_fn_track_caller)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +note: the lint level is defined here + --> $DIR/async-closure-gate.rs:6:9 + | +LL | #![deny(ungated_async_fn_track_caller)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/async-await/track-caller/async-closure-gate.nofeat.stderr b/tests/ui/async-await/track-caller/async-closure-gate.nofeat.stderr index 6887a904211ec..fb774290bde4e 100644 --- a/tests/ui/async-await/track-caller/async-closure-gate.nofeat.stderr +++ b/tests/ui/async-await/track-caller/async-closure-gate.nofeat.stderr @@ -1,7 +1,7 @@ error[E0658]: `#[track_caller]` on closures is currently unstable - --> $DIR/async-closure-gate.rs:8:13 + --> $DIR/async-closure-gate.rs:11:13 | -LL | let _ = #[track_caller] async || { +LL | let _ = #[track_caller] | ^^^^^^^^^^^^^^^ | = note: see issue #87417 for more information @@ -9,9 +9,9 @@ LL | let _ = #[track_caller] async || { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `#[track_caller]` on closures is currently unstable - --> $DIR/async-closure-gate.rs:15:13 + --> $DIR/async-closure-gate.rs:19:13 | -LL | let _ = #[track_caller] async || { +LL | let _ = #[track_caller] | ^^^^^^^^^^^^^^^ | = note: see issue #87417 for more information @@ -19,9 +19,9 @@ LL | let _ = #[track_caller] async || { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `#[track_caller]` on closures is currently unstable - --> $DIR/async-closure-gate.rs:21:13 + --> $DIR/async-closure-gate.rs:25:13 | -LL | let _ = #[track_caller] || { +LL | let _ = #[track_caller] | ^^^^^^^^^^^^^^^ | = note: see issue #87417 for more information @@ -29,9 +29,9 @@ LL | let _ = #[track_caller] || { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `#[track_caller]` on closures is currently unstable - --> $DIR/async-closure-gate.rs:29:17 + --> $DIR/async-closure-gate.rs:32:17 | -LL | let _ = #[track_caller] || { +LL | let _ = #[track_caller] | ^^^^^^^^^^^^^^^ | = note: see issue #87417 for more information @@ -39,9 +39,9 @@ LL | let _ = #[track_caller] || { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `#[track_caller]` on closures is currently unstable - --> $DIR/async-closure-gate.rs:37:9 + --> $DIR/async-closure-gate.rs:40:9 | -LL | #[track_caller] || { +LL | #[track_caller] | ^^^^^^^^^^^^^^^ | = note: see issue #87417 for more information @@ -49,48 +49,15 @@ LL | #[track_caller] || { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `#[track_caller]` on closures is currently unstable - --> $DIR/async-closure-gate.rs:47:13 + --> $DIR/async-closure-gate.rs:49:13 | -LL | #[track_caller] || { +LL | #[track_caller] | ^^^^^^^^^^^^^^^ | = note: see issue #87417 for more information = help: add `#![feature(closure_track_caller)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0308]: mismatched types - --> $DIR/async-closure-gate.rs:27:5 - | -LL | fn foo3() { - | - help: try adding a return type: `-> impl Future` -LL | / async { -LL | | -LL | | let _ = #[track_caller] || { -... | -LL | | } - | |_____^ expected `()`, found `async` block - | - = note: expected unit type `()` - found `async` block `{async block@$DIR/async-closure-gate.rs:27:5: 27:10}` - -error[E0308]: mismatched types - --> $DIR/async-closure-gate.rs:44:5 - | -LL | fn foo5() { - | - help: try adding a return type: `-> impl Future` -LL | / async { -LL | | -LL | | let _ = || { -LL | | #[track_caller] || { -... | -LL | | }; -LL | | } - | |_____^ expected `()`, found `async` block - | - = note: expected unit type `()` - found `async` block `{async block@$DIR/async-closure-gate.rs:44:5: 44:10}` - -error: aborting due to 8 previous errors +error: aborting due to 6 previous errors -Some errors have detailed explanations: E0308, E0658. -For more information about an error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/async-await/track-caller/async-closure-gate.rs b/tests/ui/async-await/track-caller/async-closure-gate.rs index e72ce2afa45fd..13d3a5787ca9d 100644 --- a/tests/ui/async-await/track-caller/async-closure-gate.rs +++ b/tests/ui/async-await/track-caller/async-closure-gate.rs @@ -1,52 +1,54 @@ //@ edition:2021 -//@ revisions: afn nofeat +//@ revisions: afn cls afn_cls nofeat +//@[afn_cls] check-pass #![feature(stmt_expr_attributes)] -#![cfg_attr(afn, feature(async_fn_track_caller))] +#![deny(ungated_async_fn_track_caller)] +#![cfg_attr(any(afn, afn_cls), feature(async_fn_track_caller))] +#![cfg_attr(any(cls, afn_cls), feature(closure_track_caller))] fn main() { - let _ = #[track_caller] async || { - //~^ ERROR `#[track_caller]` on closures is currently unstable [E0658] - }; + let _ = #[track_caller] + //[nofeat,afn]~^ ERROR `#[track_caller]` on closures is currently unstable [E0658] + async || {}; } #[track_caller] +//[cls]~^ ERROR `#[track_caller]` on async functions is a no-op async fn foo() { - let _ = #[track_caller] async || { - //~^ ERROR `#[track_caller]` on closures is currently unstable [E0658] - }; + let _ = #[track_caller] + //[nofeat,afn]~^ ERROR `#[track_caller]` on closures is currently unstable [E0658] + async || {}; } async fn foo2() { - let _ = #[track_caller] || { - //~^ ERROR `#[track_caller]` on closures is currently unstable [E0658] - }; + let _ = #[track_caller] + //[nofeat,afn]~^ ERROR `#[track_caller]` on closures is currently unstable [E0658] + || {}; } fn foo3() { - async { - //~^ ERROR mismatched types - let _ = #[track_caller] || { - //~^ ERROR `#[track_caller]` on closures is currently unstable [E0658] - }; - } + let _ = async { + let _ = #[track_caller] + //[nofeat,afn]~^ ERROR `#[track_caller]` on closures is currently unstable [E0658] + || {}; + }; } async fn foo4() { let _ = || { - #[track_caller] || { - //~^ ERROR `#[track_caller]` on closures is currently unstable [E0658] - }; + #[track_caller] + //[nofeat,afn]~^ ERROR `#[track_caller]` on closures is currently unstable [E0658] + || {}; }; } fn foo5() { - async { - //~^ ERROR mismatched types + let _ = async { let _ = || { - #[track_caller] || { - //~^ ERROR `#[track_caller]` on closures is currently unstable [E0658] - }; + #[track_caller] + //[nofeat,afn]~^ ERROR `#[track_caller]` on closures is currently unstable [E0658] + || {}; }; - } + }; } diff --git a/tests/ui/async-await/track-caller/panic-track-caller.cls.stderr b/tests/ui/async-await/track-caller/panic-track-caller.cls.stderr index 464cbfba2acfe..5611e53f50a40 100644 --- a/tests/ui/async-await/track-caller/panic-track-caller.cls.stderr +++ b/tests/ui/async-await/track-caller/panic-track-caller.cls.stderr @@ -1,9 +1,9 @@ warning: `#[track_caller]` on async functions is a no-op - --> $DIR/panic-track-caller.rs:53:1 + --> $DIR/panic-track-caller.rs:59:1 | LL | #[track_caller] | ^^^^^^^^^^^^^^^ -... +LL | LL | / async fn bar_track_caller() { LL | | panic!() LL | | } @@ -15,11 +15,11 @@ LL | | } = 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:67:5 + --> $DIR/panic-track-caller.rs:73:5 | LL | #[track_caller] | ^^^^^^^^^^^^^^^ -... +LL | LL | / async fn bar_assoc() { LL | | panic!(); LL | | } @@ -29,5 +29,20 @@ LL | | } = help: add `#![feature(async_fn_track_caller)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -warning: 2 warnings emitted +warning: `#[track_caller]` on async functions is a no-op + --> $DIR/panic-track-caller.rs:108:1 + | +LL | #[track_caller] + | ^^^^^^^^^^^^^^^ +LL | +LL | / async fn bar_manual_poll() { +LL | | panic!(); +LL | | } + | |_- this function will not propagate the caller location + | + = note: see issue #110011 for more information + = help: add `#![feature(async_fn_track_caller)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +warning: 3 warnings emitted 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 index 464cbfba2acfe..5611e53f50a40 100644 --- a/tests/ui/async-await/track-caller/panic-track-caller.nofeat.stderr +++ b/tests/ui/async-await/track-caller/panic-track-caller.nofeat.stderr @@ -1,9 +1,9 @@ warning: `#[track_caller]` on async functions is a no-op - --> $DIR/panic-track-caller.rs:53:1 + --> $DIR/panic-track-caller.rs:59:1 | LL | #[track_caller] | ^^^^^^^^^^^^^^^ -... +LL | LL | / async fn bar_track_caller() { LL | | panic!() LL | | } @@ -15,11 +15,11 @@ LL | | } = 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:67:5 + --> $DIR/panic-track-caller.rs:73:5 | LL | #[track_caller] | ^^^^^^^^^^^^^^^ -... +LL | LL | / async fn bar_assoc() { LL | | panic!(); LL | | } @@ -29,5 +29,20 @@ LL | | } = help: add `#![feature(async_fn_track_caller)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -warning: 2 warnings emitted +warning: `#[track_caller]` on async functions is a no-op + --> $DIR/panic-track-caller.rs:108:1 + | +LL | #[track_caller] + | ^^^^^^^^^^^^^^^ +LL | +LL | / async fn bar_manual_poll() { +LL | | panic!(); +LL | | } + | |_- this function will not propagate the caller location + | + = note: see issue #110011 for more information + = help: add `#![feature(async_fn_track_caller)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +warning: 3 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 index bd12bf11d6c84..294150500170d 100644 --- a/tests/ui/async-await/track-caller/panic-track-caller.rs +++ b/tests/ui/async-await/track-caller/panic-track-caller.rs @@ -1,11 +1,16 @@ +// This test is duplicated (with changes) at +// src/tools/miri/tests/pass/async-panic-track-caller.rs + +// FIXME: catch_unwind is broken in gcc. Will be fixed in the next rustc_codegen_gcc sync. +//@ ignore-backends: gcc //@ run-pass //@ edition:2021 -//@ revisions: afn cls nofeat +//@ revisions: afn cls afn_cls nofeat //@ needs-unwind // gate-test-async_fn_track_caller #![feature(stmt_expr_attributes)] -#![cfg_attr(afn, feature(async_fn_track_caller))] -#![cfg_attr(cls, feature(closure_track_caller))] +#![cfg_attr(any(afn, afn_cls), feature(async_fn_track_caller))] +#![cfg_attr(any(cls, afn_cls), feature(closure_track_caller))] #![allow(unused)] use std::future::Future; @@ -47,53 +52,71 @@ async fn bar() { } async fn foo() { - bar().await + let future = bar(); + future.await; } #[track_caller] -//[cls]~^ WARN `#[track_caller]` on async functions is a no-op -//[nofeat]~^^ WARN `#[track_caller]` on async functions is a no-op +//[cls,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 + let future = bar_track_caller(); + future.await; } struct Foo; impl Foo { #[track_caller] - //[cls]~^ WARN `#[track_caller]` on async functions is a no-op - //[nofeat]~^^ WARN `#[track_caller]` on async functions is a no-op + //[cls,nofeat]~^ WARN `#[track_caller]` on async functions is a no-op async fn bar_assoc() { panic!(); } } async fn foo_assoc() { - Foo::bar_assoc().await + let future = Foo::bar_assoc(); + future.await; } -// Since compilation is expected to fail for this fn when using -// `nofeat`, we test that separately in `async-closure-gate.rs` -#[cfg(cls)] +// Since compilation is expected to fail for this fn when `closure_track_caller` +// is disabled, we test that separately in `async-closure-gate.rs` +#[cfg(any(cls, afn_cls))] async fn foo_closure() { - let c = #[track_caller] async || { + let closure = #[track_caller] + async || { panic!(); }; - c().await + let future = closure(); + future.await; } -// Since compilation is expected to fail for this fn when using -// `nofeat`, we test that separately in `async-block.rs` -#[cfg(cls)] +// Since compilation is expected to fail for this fn when `closure_track_caller` +// is disabled, we test that separately in `async-closure-gate.rs` +#[cfg(any(cls, afn_cls))] async fn foo_block() { - let a = #[track_caller] async { + let future = #[track_caller] + async { panic!(); }; - a.await + future.await; +} + +#[track_caller] +//[cls,nofeat]~^ WARN `#[track_caller]` on async functions is a no-op +async fn bar_manual_poll() { + panic!(); +} + +fn foo_manual_poll() { + let future = bar_manual_poll(); + let future = std::pin::pin!(future); + let mut cx = std::task::Context::from_waker(std::task::Waker::noop()); + let res = future.poll(&mut cx); + assert_eq!(res, std::task::Poll::Ready(())); } fn panicked_at(f: impl FnOnce() + panic::UnwindSafe) -> u32 { @@ -112,23 +135,36 @@ fn panicked_at(f: impl FnOnce() + panic::UnwindSafe) -> u32 { x } +// FIXME(async_fn_track_caller): Currently, #[track_caller] on an async function +// uses the location where the future is awaited or polled. +// The correct behavior as per T-lang is to use the location where the function is called. fn main() { - assert_eq!(panicked_at(|| block_on(foo())), 46 -); + assert_eq!(panicked_at(|| block_on(foo())), 51); - #[cfg(afn)] - assert_eq!(panicked_at(|| block_on(foo_track_caller())), 61); + #[cfg(any(afn, afn_cls))] + assert_eq!(panicked_at(|| block_on(foo_track_caller())), 67); #[cfg(any(cls, nofeat))] - assert_eq!(panicked_at(|| block_on(foo_track_caller())), 57); + assert_eq!(panicked_at(|| block_on(foo_track_caller())), 62); - #[cfg(afn)] - assert_eq!(panicked_at(|| block_on(foo_assoc())), 76); + #[cfg(any(afn, afn_cls))] + assert_eq!(panicked_at(|| block_on(foo_assoc())), 82); #[cfg(any(cls, nofeat))] - assert_eq!(panicked_at(|| block_on(foo_assoc())), 71); + assert_eq!(panicked_at(|| block_on(foo_assoc())), 76); + // FIXME(closure_track_caller): if closure_track_caller is enabled, but + // async_fn_track_caller is disabled, then #[track_caller] on async closures + // silently do nothing. Either it should function, or we should emit a warning. + // See #161961 #[cfg(cls)] - assert_eq!(panicked_at(|| block_on(foo_closure())), 84); + assert_eq!(panicked_at(|| block_on(foo_closure())), 91); + #[cfg(afn_cls)] + assert_eq!(panicked_at(|| block_on(foo_closure())), 94); - #[cfg(cls)] - assert_eq!(panicked_at(|| block_on(foo_block())), 96); + #[cfg(any(cls, afn_cls))] + assert_eq!(panicked_at(|| block_on(foo_block())), 105); + + #[cfg(any(afn, afn_cls))] + assert_eq!(panicked_at(|| foo_manual_poll()), 118); + #[cfg(any(cls, nofeat))] + assert_eq!(panicked_at(|| foo_manual_poll()), 111); }