Skip to content

Commit 243a3e2

Browse files
committed
attributes: fix compile error with instrumented async functions (#1616)
## Motivation The changes in #1607 introduced a potential compilation error when using the `#[instrument]` attribute on `async fn`s that return a type that includes a closure or is otherwise unnameable. This is because the future's body code was quoted in two separate places in order to have a separate branch when the span is statically disabled. This means that when a closure is returned, it will technically have two distinct types based on whether or not the span is enabled, since it originates from two separate source code locations (although `quote_spanned!` obscures this, so the compiler diagnostic will appear to have two closures originating from the same location). ## Solution This branch fixes this issue by changing the code generated for `#[instrument]`ed async functions. Unfortunately, for async functions, we can't have the optimization of not creating the span at all when the level is disabled, because we need to create the span _before_ creating the future, as it may borrow arguments. I've also added tests reproducing issue #1615 Fixes #1615
1 parent ac74ba0 commit 243a3e2

File tree

2 files changed

+20
-4
lines changed

2 files changed

+20
-4
lines changed

tracing-attributes/src/lib.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -731,15 +731,16 @@ fn gen_block(
731731
};
732732

733733
return quote_spanned!(block.span()=>
734-
if tracing::level_enabled!(#level) {
735-
let __tracing_attr_span = #span;
734+
let __tracing_attr_span = #span;
735+
let __tracing_instrument_future = #mk_fut;
736+
if !__tracing_attr_span.is_disabled() {
736737
tracing::Instrument::instrument(
737-
#mk_fut,
738+
__tracing_instrument_future,
738739
__tracing_attr_span
739740
)
740741
.await
741742
} else {
742-
#mk_fut.await
743+
__tracing_instrument_future.await
743744
}
744745
);
745746
}

tracing-attributes/tests/async_fn.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,21 @@ async fn test_async_fn(polls: usize) -> Result<(), ()> {
1515
future.await
1616
}
1717

18+
// Reproduces a compile error when returning an `impl Trait` from an
19+
// instrumented async fn (see https://github.com/tokio-rs/tracing/issues/1615)
20+
#[instrument]
21+
async fn test_ret_impl_trait(n: i32) -> Result<impl Iterator<Item = i32>, ()> {
22+
let n = n;
23+
Ok((0..10).filter(move |x| *x < n))
24+
}
25+
26+
// Reproduces a compile error when returning an `impl Trait` from an
27+
// instrumented async fn (see https://github.com/tokio-rs/tracing/issues/1615)
28+
#[instrument(err)]
29+
async fn test_ret_impl_trait_err(n: i32) -> Result<impl Iterator<Item = i32>, &'static str> {
30+
Ok((0..10).filter(move |x| *x < n))
31+
}
32+
1833
#[instrument]
1934
async fn test_async_fn_empty() {}
2035

0 commit comments

Comments
 (0)