Skip to content

Commit

Permalink
attributes: remove extra braces around async blocks (#2090)
Browse files Browse the repository at this point in the history
## Motivation

When using an `async` block (as an alternative to `async fn`, e.g. when
implementing a trait), `#[instrument]` adds extra braces around the
wrapped `async` block. This causes `rustc` to emit an `unused_braces`
lint in some cases (usually for single-line `async` blocks, as far as I
can tell). See #1831 for an example.

## Solution

Since the `async` block extracted by `AsyncInfo::from_fn` already has
braces around its statements, there's no need to wrap it with additional
braces. This updates `gen_block` to remove those extra braces when
generating the code providing the value of
`__tracing_instrument_future`.

- [x] add repros for `unused_braces` issue
- [x] remove extra braces from async blocks

Fixes #1831
  • Loading branch information
jarrodldavis authored and hawkw committed Apr 26, 2022
1 parent befdca0 commit 0d13e5b
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 4 deletions.
8 changes: 4 additions & 4 deletions tracing-attributes/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ fn gen_block<B: ToTokens>(
let mk_fut = match (err_event, ret_event) {
(Some(err_event), Some(ret_event)) => quote_spanned!(block.span()=>
async move {
match async move { #block }.await {
match async move #block.await {
#[allow(clippy::unit_arg)]
Ok(x) => {
#ret_event;
Expand All @@ -232,7 +232,7 @@ fn gen_block<B: ToTokens>(
),
(Some(err_event), None) => quote_spanned!(block.span()=>
async move {
match async move { #block }.await {
match async move #block.await {
#[allow(clippy::unit_arg)]
Ok(x) => Ok(x),
Err(e) => {
Expand All @@ -244,13 +244,13 @@ fn gen_block<B: ToTokens>(
),
(None, Some(ret_event)) => quote_spanned!(block.span()=>
async move {
let x = async move { #block }.await;
let x = async move #block.await;
#ret_event;
x
}
),
(None, None) => quote_spanned!(block.span()=>
async move { #block }
async move #block
),
};

Expand Down
17 changes: 17 additions & 0 deletions tracing-attributes/tests/async_fn.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use tracing_mock::*;

use std::convert::Infallible;
use std::{future::Future, pin::Pin, sync::Arc};
use tracing::subscriber::with_default;
use tracing_attributes::instrument;
Expand Down Expand Up @@ -51,6 +52,22 @@ async fn repro_1613_2() {
// else
}

// Reproduces https://github.com/tokio-rs/tracing/issues/1831
#[instrument]
#[deny(unused_braces)]
fn repro_1831() -> Pin<Box<dyn Future<Output = ()>>> {
Box::pin(async move {})
}

// This replicates the pattern used to implement async trait methods on nightly using the
// `type_alias_impl_trait` feature
#[instrument(ret, err)]
#[deny(unused_braces)]
#[allow(clippy::manual_async_fn)]
fn repro_1831_2() -> impl Future<Output = Result<(), Infallible>> {
async { Ok(()) }
}

#[test]
fn async_fn_only_enters_for_polls() {
let (subscriber, handle) = subscriber::mock()
Expand Down

0 comments on commit 0d13e5b

Please sign in to comment.