Skip to content

Commit 0928c37

Browse files
committed
Let dead_code lint work on #[instrumented functions
Closes (partially?) #1366
1 parent bdbaf80 commit 0928c37

File tree

4 files changed

+73
-28
lines changed

4 files changed

+73
-28
lines changed

tracing-attributes/src/expand.rs

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::iter;
22

33
use proc_macro2::TokenStream;
4+
use quote::TokenStreamExt;
45
use quote::{quote, quote_spanned, ToTokens};
56
use syn::visit_mut::VisitMut;
67
use syn::{
@@ -29,6 +30,7 @@ pub(crate) fn gen_function<'a, B: ToTokens + 'a>(
2930
inner_attrs,
3031
vis,
3132
sig,
33+
brace_token,
3234
block,
3335
} = input;
3436

@@ -44,9 +46,12 @@ pub(crate) fn gen_function<'a, B: ToTokens + 'a>(
4446
syn::Generics {
4547
params: gen_params,
4648
where_clause,
47-
..
49+
lt_token,
50+
gt_token,
4851
},
49-
..
52+
fn_token,
53+
paren_token,
54+
variadic,
5055
} = sig;
5156

5257
let warnings = args.warnings();
@@ -65,9 +70,14 @@ pub(crate) fn gen_function<'a, B: ToTokens + 'a>(
6570
// exactly that way for it to do its magic.
6671
let fake_return_edge = quote_spanned! {return_span=>
6772
#[allow(
68-
unknown_lints, unreachable_code, clippy::diverging_sub_expression,
69-
clippy::let_unit_value, clippy::unreachable, clippy::let_with_type_underscore,
70-
clippy::empty_loop
73+
unknown_lints,
74+
unreachable_code,
75+
clippy::diverging_sub_expression,
76+
clippy::empty_loop,
77+
clippy::let_unit_value,
78+
clippy::let_with_type_underscore,
79+
clippy::needless_return,
80+
clippy::unreachable
7181
)]
7282
if false {
7383
let __tracing_attr_fake_return: #return_type = loop {};
@@ -90,16 +100,27 @@ pub(crate) fn gen_function<'a, B: ToTokens + 'a>(
90100
self_type,
91101
);
92102

93-
quote!(
103+
let mut result = quote!(
94104
#(#outer_attrs) *
95-
#vis #constness #asyncness #unsafety #abi fn #ident<#gen_params>(#params) #output
96-
#where_clause
97-
{
98-
#(#inner_attrs) *
99-
#warnings
100-
#body
101-
}
102-
)
105+
#vis #constness #asyncness #unsafety #abi #fn_token #ident
106+
#lt_token #gen_params #gt_token
107+
);
108+
109+
paren_token.surround(&mut result, |tokens| {
110+
params.to_tokens(tokens);
111+
variadic.to_tokens(tokens);
112+
});
113+
114+
output.to_tokens(&mut result);
115+
where_clause.to_tokens(&mut result);
116+
117+
brace_token.surround(&mut result, |tokens| {
118+
tokens.append_all(inner_attrs);
119+
warnings.to_tokens(tokens);
120+
body.to_tokens(tokens);
121+
});
122+
123+
result
103124
}
104125

105126
/// Instrument a block

tracing-attributes/src/lib.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,10 @@
8080
)]
8181

8282
use proc_macro2::TokenStream;
83+
use quote::TokenStreamExt;
8384
use quote::{quote, ToTokens};
8485
use syn::parse::{Parse, ParseStream};
86+
use syn::token::Brace;
8587
use syn::{Attribute, ItemFn, Signature, Visibility};
8688

8789
mod attr;
@@ -428,6 +430,7 @@ struct MaybeItemFn {
428430
inner_attrs: Vec<Attribute>,
429431
vis: Visibility,
430432
sig: Signature,
433+
brace_token: Brace,
431434
block: TokenStream,
432435
}
433436

@@ -438,6 +441,7 @@ impl MaybeItemFn {
438441
inner_attrs: &self.inner_attrs,
439442
vis: &self.vis,
440443
sig: &self.sig,
444+
brace_token: &self.brace_token,
441445
block: &self.block,
442446
}
443447
}
@@ -451,12 +455,15 @@ impl Parse for MaybeItemFn {
451455
let vis: Visibility = input.parse()?;
452456
let sig: Signature = input.parse()?;
453457
let inner_attrs = input.call(Attribute::parse_inner)?;
454-
let block: TokenStream = input.parse()?;
458+
let block;
459+
let brace_token = syn::braced!(block in input);
460+
let block: TokenStream = block.call(|buffer| buffer.parse())?;
455461
Ok(Self {
456462
outer_attrs,
457463
inner_attrs,
458464
vis,
459465
sig,
466+
brace_token,
460467
block,
461468
})
462469
}
@@ -474,12 +481,15 @@ impl From<ItemFn> for MaybeItemFn {
474481
let (outer_attrs, inner_attrs) = attrs
475482
.into_iter()
476483
.partition(|attr| attr.style == syn::AttrStyle::Outer);
484+
let mut block_tokens = TokenStream::new();
485+
block_tokens.append_all(block.stmts);
477486
Self {
478487
outer_attrs,
479488
inner_attrs,
480489
vis,
481490
sig,
482-
block: block.to_token_stream(),
491+
brace_token: block.brace_token,
492+
block: block_tokens,
483493
}
484494
}
485495
}
@@ -492,5 +502,6 @@ struct MaybeItemFnRef<'a, B: ToTokens> {
492502
inner_attrs: &'a Vec<Attribute>,
493503
vis: &'a Visibility,
494504
sig: &'a Signature,
505+
brace_token: &'a Brace,
495506
block: &'a B,
496507
}

tracing-attributes/tests/dead_code.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
use tracing_attributes::instrument;
2+
3+
#[deny(unfulfilled_lint_expectations)]
4+
#[expect(dead_code)]
5+
#[instrument]
6+
fn unused() {}
7+
8+
#[expect(dead_code)]
9+
#[instrument]
10+
async fn unused_async() {}

tracing-attributes/tests/ui/async_instrument.stderr

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,16 @@ note: return type inferred to be `String` here
2525
| ^^^^^^
2626

2727
error[E0277]: `(&str,)` doesn't implement `std::fmt::Display`
28-
--> tests/ui/async_instrument.rs:14:1
28+
--> tests/ui/async_instrument.rs:15:57
2929
|
30-
14 | #[tracing::instrument]
31-
| ^^^^^^^^^^^^^^^^^^^^^^ `(&str,)` cannot be formatted with the default formatter
30+
15 | async fn opaque_unsatisfied() -> impl std::fmt::Display {
31+
| _________________________________________________________^
32+
16 | | ("",)
33+
17 | | }
34+
| |_^ `(&str,)` cannot be formatted with the default formatter
3235
|
3336
= help: the trait `std::fmt::Display` is not implemented for `(&str,)`
3437
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
35-
= note: this error originates in the attribute macro `tracing::instrument` (in Nightly builds, run with -Z macro-backtrace for more info)
3638

3739
error[E0277]: `(&str,)` doesn't implement `std::fmt::Display`
3840
--> tests/ui/async_instrument.rs:15:34
@@ -88,11 +90,12 @@ note: return type inferred to be `String` here
8890
| ^^^^^^
8991

9092
error[E0308]: mismatched types
91-
--> tests/ui/async_instrument.rs:42:35
92-
|
93-
42 | async fn extra_semicolon() -> i32 {
94-
| ___________________________________^
95-
43 | | 1;
96-
| | - help: remove this semicolon to return this value
97-
44 | | }
98-
| |_^ expected `i32`, found `()`
93+
--> tests/ui/async_instrument.rs:41:1
94+
|
95+
41 | #[tracing::instrument]
96+
| ^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `()`
97+
42 | async fn extra_semicolon() -> i32 {
98+
43 | 1;
99+
| - help: remove this semicolon to return this value
100+
|
101+
= note: this error originates in the attribute macro `tracing::instrument` (in Nightly builds, run with -Z macro-backtrace for more info)

0 commit comments

Comments
 (0)