Skip to content

Commit f7cd4c4

Browse files
committed
don't expand given block twice
1 parent eccd0ea commit f7cd4c4

File tree

2 files changed

+84
-14
lines changed

2 files changed

+84
-14
lines changed

tracing-attributes/src/expand.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,8 @@ fn gen_block<B: ToTokens>(
197197
};
198198

199199
let ret_event = match args.ret_mode {
200-
Some(FormatMode::Display) => Some(quote!(tracing::trace!(return = %#block))),
201-
Some(FormatMode::Debug) => Some(quote!(tracing::trace!(return = ?#block))),
200+
Some(FormatMode::Display) => Some(quote!(tracing::trace!(return = %x))),
201+
Some(FormatMode::Debug) => Some(quote!(tracing::trace!(return = ?x))),
202202
_ => None,
203203
};
204204

@@ -207,14 +207,19 @@ fn gen_block<B: ToTokens>(
207207
// which is `instrument`ed using `tracing-futures`. Otherwise, this will
208208
// enter the span and then perform the rest of the body.
209209
// If `err` is in args, instrument any resulting `Err`s.
210+
// If `ret` is in args, instrument any resulting `Ok`s when the function
211+
// returns `Result`s, otherwise instrument any resulting values.
210212
if async_context {
211213
let mk_fut = match (err_event, ret_event) {
212214
(Some(err_event), Some(ret_event)) => quote_spanned!(block.span()=>
213215
async move {
214216
#ret_event;
215217
match async move { #block }.await {
216218
#[allow(clippy::unit_arg)]
217-
Ok(x) => Ok(x),
219+
Ok(x) => {
220+
#ret_event;
221+
Ok(x)
222+
},
218223
Err(e) => {
219224
#err_event;
220225
Err(e)
@@ -236,8 +241,9 @@ fn gen_block<B: ToTokens>(
236241
),
237242
(None, Some(ret_event)) => quote_spanned!(block.span()=>
238243
async move {
244+
let x = async move { #block }.await;
239245
#ret_event;
240-
#block
246+
x
241247
}
242248
),
243249
(None, None) => quote_spanned!(block.span()=>
@@ -282,11 +288,13 @@ fn gen_block<B: ToTokens>(
282288
match (err_event, ret_event) {
283289
(Some(err_event), Some(ret_event)) => quote_spanned! {block.span()=>
284290
#span
285-
#ret_event;
286291
#[allow(clippy::redundant_closure_call)]
287292
match (move || #block)() {
288293
#[allow(clippy::unit_arg)]
289-
Ok(x) => Ok(x),
294+
Ok(x) => {
295+
#ret_event;
296+
Ok(x)
297+
},
290298
Err(e) => {
291299
#err_event;
292300
Err(e)
@@ -307,8 +315,9 @@ fn gen_block<B: ToTokens>(
307315
),
308316
(None, Some(ret_event)) => quote_spanned!(block.span()=>
309317
#span
318+
let x = (move || #block)();
310319
#ret_event;
311-
#block
320+
x
312321
),
313322
(None, None) => quote_spanned!(block.span() =>
314323
// Because `quote` produces a stream of tokens _without_ whitespace, the

tracing-attributes/tests/ret.rs

Lines changed: 68 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,38 @@ fn test() {
3535
handle.assert_finished();
3636
}
3737

38+
#[instrument(ret)]
39+
fn ret_mut(a: &mut i32) -> i32 {
40+
*a *= 2;
41+
tracing::info!(?a);
42+
*a
43+
}
44+
45+
#[test]
46+
fn test_mut() {
47+
let span = span::mock().named("ret_mut");
48+
let (collector, handle) = collector::mock()
49+
.new_span(span.clone())
50+
.enter(span.clone())
51+
.event(
52+
event::mock()
53+
.with_fields(field::mock("a").with_value(&tracing::field::display(2)))
54+
.at_level(Level::INFO),
55+
)
56+
.event(
57+
event::mock()
58+
.with_fields(field::mock("return").with_value(&tracing::field::display(2)))
59+
.at_level(Level::TRACE),
60+
)
61+
.exit(span.clone())
62+
.drop_span(span)
63+
.done()
64+
.run_with_handle();
65+
66+
with_default(collector, || ret_mut(&mut 1));
67+
handle.assert_finished();
68+
}
69+
3870
#[instrument(ret)]
3971
async fn ret_async() -> i32 {
4072
42
@@ -121,14 +153,14 @@ fn test_ret_and_err() {
121153
let (collector, handle) = collector::mock()
122154
.new_span(span.clone())
123155
.enter(span.clone())
124-
.event(event::mock().with_fields(
125-
field::mock("return").with_value(&tracing::field::debug(u8::try_from(1234))),
126-
))
127156
.event(
128-
event::mock().with_fields(
129-
field::mock("error")
130-
.with_value(&tracing::field::display(u8::try_from(1234).unwrap_err())),
131-
),
157+
event::mock()
158+
.with_fields(
159+
field::mock("error")
160+
.with_value(&tracing::field::display(u8::try_from(1234).unwrap_err()))
161+
.only(),
162+
)
163+
.at_level(Level::ERROR),
132164
)
133165
.exit(span.clone())
134166
.drop_span(span)
@@ -138,3 +170,32 @@ fn test_ret_and_err() {
138170
with_default(collector, || ret_and_err().ok());
139171
handle.assert_finished();
140172
}
173+
174+
#[instrument(err, ret(Debug))]
175+
fn ret_and_ok() -> Result<u8, TryFromIntError> {
176+
u8::try_from(123)
177+
}
178+
179+
#[test]
180+
fn test_ret_and_ok() {
181+
let span = span::mock().named("ret_and_ok");
182+
let (collector, handle) = collector::mock()
183+
.new_span(span.clone())
184+
.enter(span.clone())
185+
.event(
186+
event::mock()
187+
.with_fields(
188+
field::mock("return")
189+
.with_value(&tracing::field::display(u8::try_from(123).unwrap()))
190+
.only(),
191+
)
192+
.at_level(Level::TRACE),
193+
)
194+
.exit(span.clone())
195+
.drop_span(span)
196+
.done()
197+
.run_with_handle();
198+
199+
with_default(collector, || ret_and_ok().ok());
200+
handle.assert_finished();
201+
}

0 commit comments

Comments
 (0)