From 7a0ca807be828606b14cff2c9a3d150ff9d999ce Mon Sep 17 00:00:00 2001 From: Martin Grigorov Date: Thu, 11 Sep 2025 10:18:40 +0300 Subject: [PATCH] time: add `#[track_caller]` to `FutureExt::timeout` (#7588) Signed-off-by: Martin Tzvetanov Grigorov --- tokio-util/src/future.rs | 1 + tokio-util/tests/panic.rs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/tokio-util/src/future.rs b/tokio-util/src/future.rs index 408de66b9..8a8313f04 100644 --- a/tokio-util/src/future.rs +++ b/tokio-util/src/future.rs @@ -26,6 +26,7 @@ pub trait FutureExt: Future { /// assert!(res.is_err()); /// # } /// ``` + #[track_caller] fn timeout(self, timeout: std::time::Duration) -> tokio::time::Timeout where Self: Sized, diff --git a/tokio-util/tests/panic.rs b/tokio-util/tests/panic.rs index 853f132fc..010eda7c2 100644 --- a/tokio-util/tests/panic.rs +++ b/tokio-util/tests/panic.rs @@ -217,6 +217,23 @@ fn delay_queue_reserve_panic_caller() -> Result<(), Box> { Ok(()) } +#[test] +fn future_ext_to_panic_caller() -> Result<(), Box> { + use tokio::{sync::oneshot, time::Duration}; + use tokio_util::future::FutureExt; + + let panic_location_file = test_panic(|| { + let (_tx, rx) = oneshot::channel::<()>(); + // this panics because there is no runtime available + let _res = rx.timeout(Duration::from_millis(10)); + }); + + // The panic location should be in this file + assert_eq!(&panic_location_file.unwrap(), file!()); + + Ok(()) +} + fn basic() -> Runtime { tokio::runtime::Builder::new_current_thread() .enable_all()