tracing icon indicating copy to clipboard operation
tracing copied to clipboard

`tracing::instrument(ret)` errors on function with `&mut` args returning `&`/`&mut`

Open jdygert-spok opened this issue 1 year ago • 0 comments

Bug Report

Version

tracing v0.1.40
tracing-attributes v0.1.27 (proc-macro)
tracing-core v0.1.32

Description

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; }
    // ...
}

jdygert-spok avatar Jan 18 '24 16:01 jdygert-spok