Repository: tokio-rs/tokio
File: tokio/src/runtime/dump.rs (Rust)

Code before:
    /// let mut test_future = std::pin::pin!(async move { tokio::task::yield_now().await; 0 });
    ///
    /// // trace it once
    /// let (trace, res) = Trace::root(std::future::poll_fn(|cx| {
    ///     let (res, trace) = Trace::capture(|| test_future.as_mut().poll(cx));
    ///     Poll::Ready((trace, res))
    /// })).await;
    ///
    /// let output = match res {
    ///    Poll::Ready(output) => output,
    ///    Poll::Pending => test_future.await,
    /// };
    ///
    /// println!("{trace}");
    /// # }
    /// ```
    ///
    /// ### Nested calls
    ///
    /// Nested calls to `capture` might return partial traces, but will not do any other undesirable behavior (for
    /// example, they will not panic).
    ///
    /// ### Unstable Implementation Details
    ///
    /// When run in tracing mode, Tokio leaf futures will return `Poll::Pending` and emit a stack trace
    /// that will be captured in the returning [`Trace`].
    pub fn capture<F, R>(f: F) -> (R, Trace)
    where
        F: FnOnce() -> R,
    {
        let (res, trace) = super::task::trace::Trace::capture(f);
        (res, Trace { inner: trace })
    }

    /// Create a root for stack traces captured using [`Trace::capture`]. Stack frames above
    /// the root will not be captured.
    ///
    /// Nesting multiple [`Root`] futures is fine. Captures will stop at the first root. Not having
    /// a [`Root`] is fine as well, but there is no guarantee on where the capture will stop.
    pub fn root<F>(f: F) -> Root<F>
    where
        F: Future,
    {
        crate::runtime::task::trace::Trace::root(f)
    }
}

impl Dump {
    pub(crate) fn new(tasks: Vec<Task>) -> Self {
        Self {
            tasks: Tasks { tasks },

Review comment (suggestion):
```suggestion
```
My inclination would be to not document this at all. As a rule, folks must not depend on futures making progress in *any* context, not just tracing. 

Code after:
    /// Example usage:
    /// ```
    /// use std::future::Future;
    /// use std::task::Poll;
    /// use tokio::runtime::dump::Trace;
    ///
    /// # async fn test_fn() {
    /// // some future
    /// let mut test_future = std::pin::pin!(async move { tokio::task::yield_now().await; 0 });
    ///
    /// // trace it once, see what it's doing
    /// let (trace, res) = Trace::root(std::future::poll_fn(|cx| {
    ///     let (res, trace) = Trace::capture(|| test_future.as_mut().poll(cx));
    ///     Poll::Ready((trace, res))
    /// })).await;
    ///
    /// // await it to let it finish, outside of a `capture`
    /// let output = match res {
    ///    Poll::Ready(output) => output,
    ///    Poll::Pending => test_future.await,
    /// };
    ///
    /// println!("{trace}");
    /// # }
    /// ```
    ///
    /// ### Nested calls
    ///
    /// Nested calls to `capture` might return partial traces, but will not do any other undesirable behavior (for
    /// example, they will not panic).
    pub fn capture<F, R>(f: F) -> (R, Trace)
    where
        F: FnOnce() -> R,
    {
        let (res, trace) = super::task::trace::Trace::capture(f);
        (res, Trace { inner: trace })
    }

    /// Create a root for stack traces captured using [`Trace::capture`]. Stack frames above
    /// the root will not be captured.
    ///
    /// Nesting multiple [`Root`] futures is fine. Captures will stop at the first root. Not having
    /// a [`Root`] is fine as well, but there is no guarantee on where the capture will stop.
    pub fn root<F>(f: F) -> Root<F>
    where
        F: Future,
    {
        crate::runtime::task::trace::Trace::root(f)
    }
}