From 35180f9e570e0d62e0678b2e27c9d0496ae9645f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Marcos?= Date: Tue, 28 Apr 2026 18:44:30 -0300 Subject: [PATCH] Add #[track_caller] and avoid unwrap_or_else to preserve caller info --- src/assert.rs | 37 +++++++++++++++++++++++++++++++------ src/cargo.rs | 11 +++++++++-- src/cmd.rs | 5 +++++ src/output.rs | 3 +++ 4 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/assert.rs b/src/assert.rs index 61e33f5..aa1bf0e 100644 --- a/src/assert.rs +++ b/src/assert.rs @@ -58,6 +58,7 @@ impl OutputAssertExt for process::Output { } impl OutputAssertExt for &mut process::Command { + #[track_caller] fn assert(self) -> Assert { let output = match self.output() { Ok(output) => output, @@ -158,7 +159,11 @@ impl Assert { /// ``` #[track_caller] pub fn success(self) -> Self { - self.try_success().unwrap_or_else(AssertError::panic) + match self.try_success() { + Ok(v) => v, + // Called manually so `#[track_caller]` is effective. + Err(e) => e.panic(), + } } /// `try_` variant of [`Assert::success`]. @@ -187,7 +192,11 @@ impl Assert { /// ``` #[track_caller] pub fn failure(self) -> Self { - self.try_failure().unwrap_or_else(AssertError::panic) + match self.try_failure() { + Ok(v) => v, + // Called manually so `#[track_caller]` is effective. + Err(e) => e.panic(), + } } /// Variant of [`Assert::failure`] that returns an [`AssertResult`]. @@ -201,7 +210,11 @@ impl Assert { /// Ensure the command aborted before returning a code. #[track_caller] pub fn interrupted(self) -> Self { - self.try_interrupted().unwrap_or_else(AssertError::panic) + match self.try_interrupted() { + Ok(v) => v, + // Called manually so `#[track_caller]` is effective. + Err(e) => e.panic(), + } } /// Variant of [`Assert::interrupted`] that returns an [`AssertResult`]. @@ -266,7 +279,11 @@ impl Assert { I: IntoCodePredicate

, P: predicates_core::Predicate, { - self.try_code(pred).unwrap_or_else(AssertError::panic) + match self.try_code(pred) { + Ok(v) => v, + // Called manually so `#[track_caller]` is effective. + Err(e) => e.panic(), + } } /// Variant of [`Assert::code`] that returns an [`AssertResult`]. @@ -364,7 +381,11 @@ impl Assert { I: IntoOutputPredicate

, P: predicates_core::Predicate<[u8]>, { - self.try_stdout(pred).unwrap_or_else(AssertError::panic) + match self.try_stdout(pred) { + Ok(v) => v, + // Called manually so `#[track_caller]` is effective. + Err(e) => e.panic(), + } } /// Variant of [`Assert::stdout`] that returns an [`AssertResult`]. @@ -460,7 +481,11 @@ impl Assert { I: IntoOutputPredicate

, P: predicates_core::Predicate<[u8]>, { - self.try_stderr(pred).unwrap_or_else(AssertError::panic) + match self.try_stderr(pred) { + Ok(v) => v, + // Called manually so `#[track_caller]` is effective. + Err(e) => e.panic(), + } } /// Variant of [`Assert::stderr`] that returns an [`AssertResult`]. diff --git a/src/cargo.rs b/src/cargo.rs index e87a7a3..974710e 100644 --- a/src/cargo.rs +++ b/src/cargo.rs @@ -228,20 +228,27 @@ impl fmt::Display for NotFoundError { /// # Panic /// /// Panicks if no binary is found +#[track_caller] pub fn cargo_bin>(name: S) -> path::PathBuf { cargo_bin_str(name.as_ref()) } +#[track_caller] fn cargo_bin_str(name: &str) -> path::PathBuf { let env_var = format!("{CARGO_BIN_EXE_}{name}"); - env::var_os(env_var) + match env::var_os(env_var) .map(|p| p.into()) .or_else(|| legacy_cargo_bin(name)) - .unwrap_or_else(|| missing_cargo_bin(name)) + { + Some(path) => path, + // Called manually so `#[track_caller]` is effective. + None => missing_cargo_bin(name), + } } const CARGO_BIN_EXE_: &str = "CARGO_BIN_EXE_"; +#[track_caller] fn missing_cargo_bin(name: &str) -> ! { let possible_names: Vec<_> = env::vars_os() .filter_map(|(k, _)| k.into_string().ok()) diff --git a/src/cmd.rs b/src/cmd.rs index 00f0da3..3bc5ce6 100644 --- a/src/cmd.rs +++ b/src/cmd.rs @@ -154,6 +154,7 @@ impl Command { /// .unwrap(); /// ``` /// + #[track_caller] pub fn unwrap(&mut self) -> process::Output { OutputOkExt::unwrap(self) } @@ -171,6 +172,7 @@ impl Command { /// ``` /// /// [Output]: std::process::Output + #[track_caller] pub fn unwrap_err(&mut self) -> OutputError { OutputOkExt::unwrap_err(self) } @@ -190,6 +192,7 @@ impl Command { /// /// [`Output`]: std::process::Output #[must_use] + #[track_caller] pub fn assert(&mut self) -> Assert { OutputAssertExt::assert(self) } @@ -631,6 +634,7 @@ impl OutputOkExt for &mut Command { } } + #[track_caller] fn unwrap_err(self) -> OutputError { match self.ok() { Ok(output) => { @@ -655,6 +659,7 @@ impl OutputOkExt for &mut Command { } impl OutputAssertExt for &mut Command { + #[track_caller] fn assert(self) -> Assert { let output = match self.output() { Ok(output) => output, diff --git a/src/output.rs b/src/output.rs index 2d49703..ab0f647 100644 --- a/src/output.rs +++ b/src/output.rs @@ -59,6 +59,7 @@ where /// ``` /// /// [`Output`]: std::process::Output + #[track_caller] fn unwrap(self) -> process::Output { match self.ok() { Ok(output) => output, @@ -81,6 +82,7 @@ where /// ``` /// /// [`Output`]: std::process::Output + #[track_caller] fn unwrap_err(self) -> OutputError { match self.ok() { Ok(output) => panic!( @@ -114,6 +116,7 @@ impl OutputOkExt for &mut process::Command { } } + #[track_caller] fn unwrap_err(self) -> OutputError { match self.ok() { Ok(output) => panic!(