When using instrument(ret) (or instrument(err)), the closure in the generated code is inferred to be Fn or FnMut, which causes compile errors when trying to return a reference to an argument.
// error: lifetime may not live long enough
// note: closure implements `Fn`, so references to captured variables can't escape the closure
#[tracing::instrument(ret)]
fn foo(x: &mut ()) -> &() {
x
}
// error: captured variable cannot escape `FnMut` closure body
#[tracing::instrument(ret)]
fn foo(x: &mut ()) -> &mut () {
x
}
Possible Solution
Force the generated closure to be FnOnce, either via a function:
fn force_fn_once<T, F: FnOnce() -> T>(f: F) -> F {
f
}
force_fn_once(move || {
// ...
})
Or by rebinding a captured variable
let outer = &mut ();
move || {
{ let inner = outer; }
// ...
}
Bug Report
Version
Description
When using
instrument(ret)
(orinstrument(err)
), the closure in the generated code is inferred to beFn
orFnMut
, which causes compile errors when trying to return a reference to an argument.Possible Solution
Force the generated closure to be
FnOnce
, either via a function:Or by rebinding a captured variable