tracing
tracing copied to clipboard
`#[tracing::instrument(err)]` fails to build when Ok variant has lifetime, "lifetime may not live long enough"
Bug Report
Version
rust-tracing-instrument-bug v0.1.0 (/foo)
└── tracing v0.1.40
├── tracing-attributes v0.1.27 (proc-macro)
└── tracing-core v0.1.32
Platform
Linux gear 6.1.59 #1-NixOS SMP PREEMPT_DYNAMIC Thu Oct 19 21:08:58 UTC 2023 x86_64 GNU/Linux
Crates
[dependencies]
tracing = "0.1.40"
Description
[tracing::instrument(ret)] fails to build in some scenarios where the return Ok value is generic over a lifetime.
$ cargo build
Compiling rust-tracing-instrument-bug v0.1.0 (/foo)
error: lifetime may not live long enough
--> src/lib.rs:16:5
|
11 | #[tracing::instrument(skip(node), err)]
| ---------------------------------------
| | |
| | return type of closure is Result<Option<Ref<'2>>, std::io::Error>
| lifetime `'1` represents this closure's body
...
16 | Ok(Some(x))
| ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
|
= note: closure implements `Fn`, so references to captured variables can't escape the closure
error: could not compile `rust-tracing-instrument-bug` (lib) due to previous error```
struct Node {}
struct Ref<'a> {
node: &'a Node,
}
fn get_ref<'a>(_node: &'a Node) -> Ref<'a> {
todo!();
}
#[tracing::instrument(skip(node), err)]
fn fails_to_compile_with_instrument<'a>(node: &'a mut Node) -> Result<Ref<'a>, std::io::Error> {
let x = get_ref(node);
Ok(x)
}
#[tracing::instrument(skip(node))]
fn works<'a>(node: &'a mut Node) -> Result<Ref<'a>, std::io::Error> {
let x = get_ref(node);
Ok(x)
}
Remove , err and it starts to build.
I had the same error. I found that I can suppress the error by capturing the mutable reference explicitly.
#[tracing::instrument(skip(node), err)]
fn fails_to_compile_with_instrument<'a>(node: &'a mut Node) -> Result<Ref<'a>, std::io::Error> {
let node = node; // capture
let x = get_ref(node);
Ok(x)
}