Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#[track_caller] does nothing on async fns #78840

Closed
ghost opened this issue Nov 7, 2020 · 7 comments · Fixed by #104219
Closed

#[track_caller] does nothing on async fns #78840

ghost opened this issue Nov 7, 2020 · 7 comments · Fixed by #104219
Assignees
Labels
A-async-await Area: Async & Await A-attributes Area: Attributes (`#[…]`, `#![…]`) AsyncAwait-Polish Async-await issues that are part of the "polish" area AsyncAwait-Triaged Async-await issues that have been triaged during a working group meeting. C-feature-request Category: A feature request, i.e: not implemented / a PR. F-track_caller `#![feature(track_caller)]`

Comments

@ghost
Copy link

ghost commented Nov 7, 2020

I tried:

#[track_caller]
async fn panic() -> ! {
    panic!();
}

fn main() {
    futures::executor::block_on(async { panic().await });
}

I expected the seventh line to be the panic location, but I got this:

thread 'main' panicked at 'explicit panic', src/main.rs:3:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
With RUST_BACKTRACE=1
thread 'main' panicked at 'explicit panic', src/main.rs:3:5
stack backtrace:
   0: std::panicking::begin_panic
             at /rustc/a601302ff0217b91589b5a7310a8a23adb843fdc/library/std/src/panicking.rs:521:12
   1: playground::panic::{{closure}}
             at ./src/main.rs:3:5
   2: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/a601302ff0217b91589b5a7310a8a23adb843fdc/library/core/src/future/mod.rs:80:19
   3: playground::main::{{closure}}
             at ./src/main.rs:7:41
   4: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/a601302ff0217b91589b5a7310a8a23adb843fdc/library/core/src/future/mod.rs:80:19
   5: futures_executor::local_pool::block_on::{{closure}}
             at ./.cargo/registry/src/gh.neting.cc-1ecc6299db9ec823/futures-executor-0.3.6/src/local_pool.rs:317:23
   6: futures_executor::local_pool::run_executor::{{closure}}
             at ./.cargo/registry/src/gh.neting.cc-1ecc6299db9ec823/futures-executor-0.3.6/src/local_pool.rs:87:37
   7: std::thread::local::LocalKey<T>::try_with
             at /rustc/a601302ff0217b91589b5a7310a8a23adb843fdc/library/std/src/thread/local.rs:272:16
   8: std::thread::local::LocalKey<T>::with
             at /rustc/a601302ff0217b91589b5a7310a8a23adb843fdc/library/std/src/thread/local.rs:248:9
   9: futures_executor::local_pool::run_executor
             at ./.cargo/registry/src/gh.neting.cc-1ecc6299db9ec823/futures-executor-0.3.6/src/local_pool.rs:83:5
  10: futures_executor::local_pool::block_on
             at ./.cargo/registry/src/gh.neting.cc-1ecc6299db9ec823/futures-executor-0.3.6/src/local_pool.rs:317:5
  11: playground::main
             at ./src/main.rs:7:5
  12: core::ops::function::FnOnce::call_once
             at /rustc/a601302ff0217b91589b5a7310a8a23adb843fdc/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Playground (tried using nightly 2020-11-06 a601302)

I can achieve the result I expected by implementing a Future manually:

#![feature(never_type)]

use std::{
    future::Future,
    pin::Pin,
    task::{Context, Poll},
};

struct Panic;

impl Future for Panic {
    type Output = !;

    #[track_caller]
    fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
        panic!()
    }
}

fn main() {
    futures::executor::block_on(async { Panic.await });
}

Output:

thread 'main' panicked at 'explicit panic', src/main.rs:21:41
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Playground

I noticed that (in the backtrace) the compiler generated a closure (Generator?) for the async fn, so #74042 may be related.

@rustbot modify labels: A-async-await A-attributes

@ghost ghost added the C-bug Category: This is a bug. label Nov 7, 2020
@rustbot rustbot added A-async-await Area: Async & Await A-attributes Area: Attributes (`#[…]`, `#![…]`) labels Nov 7, 2020
@jonas-schievink jonas-schievink added the F-track_caller `#![feature(track_caller)]` label Nov 7, 2020
@jonas-schievink
Copy link
Contributor

This seems to be working correctly. The call to panic does not actually panic, so the #[track_caller] does nothing. panic just returns a future that, when polled, will panic.

@ghost
Copy link
Author

ghost commented Nov 7, 2020

This seems to be working correctly. The call to panic does not actually panic, so the #[track_caller] does nothing. panic just returns a future that, when polled, will panic.

But I expect it to work further: automatically generates the Future I implemented manually, with #[track_caller] on Future::poll and the generated closure/Generator.

(Feature request) It's even better if #[track_caller] could work on async blocks as well.

@jonas-schievink jonas-schievink added C-feature-request Category: A feature request, i.e: not implemented / a PR. and removed C-bug Category: This is a bug. labels Nov 7, 2020
@ghost

This comment has been minimized.

@Aaron1011
Copy link
Member

Since the call to an async fn can never panic (it always returns an impl Future), I think forwarding the attribute to the returned async closure would make sense.

This would require impementing #74042 (if only on nightly), so that the desugaring can forward #[track_caller] as needed.

@ghost ghost changed the title #[track_caller] does not work on async fns #[track_caller] does nothing on async fns Nov 8, 2020
@ghost

This comment has been minimized.

@tmandry
Copy link
Member

tmandry commented Dec 11, 2020

Forwarding to the poll function does seem reasonable to me.

@anp any thoughts on this?

@tmandry tmandry added the AsyncAwait-Triaged Async-await issues that have been triaged during a working group meeting. label Dec 11, 2020
@anp
Copy link
Member

anp commented Dec 12, 2020

Forwarding to the generated future SGTM.

@eholk eholk added the AsyncAwait-Polish Async-await issues that are part of the "polish" area label Oct 7, 2022
@eholk eholk self-assigned this Oct 10, 2022
Manishearth added a commit to Manishearth/rust that referenced this issue Nov 10, 2022
… r=eholk

Support `#[track_caller]` on async fns

Adds `#[track_caller]` to the generator that is created when we desugar the async fn.

Fixes rust-lang#78840

Open questions:
- What is the performance impact of adding `#[track_caller]` to every `GenFuture`'s `poll(...)` function, even if it's unused (i.e., the parent span does not set `#[track_caller]`)? We might need to set it only conditionally, if the indirection causes overhead we don't want.
@bors bors closed this as completed in b6097f2 Nov 17, 2022
Aaron1011 pushed a commit to Aaron1011/rust that referenced this issue Jan 6, 2023
…=eholk

Support `#[track_caller]` on async fns

Adds `#[track_caller]` to the generator that is created when we desugar the async fn.

Fixes rust-lang#78840

Open questions:
- What is the performance impact of adding `#[track_caller]` to every `GenFuture`'s `poll(...)` function, even if it's unused (i.e., the parent span does not set `#[track_caller]`)? We might need to set it only conditionally, if the indirection causes overhead we don't want.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-async-await Area: Async & Await A-attributes Area: Attributes (`#[…]`, `#![…]`) AsyncAwait-Polish Async-await issues that are part of the "polish" area AsyncAwait-Triaged Async-await issues that have been triaged during a working group meeting. C-feature-request Category: A feature request, i.e: not implemented / a PR. F-track_caller `#![feature(track_caller)]`
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants