Skip to content

Commit 9e2dd0f

Browse files
ilslvdaxpeddahawkw
authored andcommitted
tracing, tracing-futures: instrument Future inside Drop (tokio-rs#2562)
## Motivation Currently it is not possible to disable ANSI in `fmt::Subscriber` without enabling the "ansi" crate feature. This makes it difficult for users to implement interoperable settings that are controllable with crate features without having to pull in the dependencies "ansi" does. I hit this while writing an application with multiple logging options set during compile-time and I wanted to cut down on dependencies if possible. ## Solution This changes `fmt::Subscriber::with_ansi()` to not require the "ansi" feature flag. This way, `with_ansi(false)` can be called even when the "ansi" feature is disabled. Calling `with_ansi(true)` when the "ansi" feature is not enabled will panic in debug mode, or print a warning if debug assertions are disabled. Co-authored-by: daxpedda <[email protected]> Co-authored-by: Eliza Weisman <[email protected]>
1 parent 5a30de9 commit 9e2dd0f

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

tracing-attributes/tests/async_fn.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ fn async_fn_nested() {
124124
.exit(span2.clone())
125125
.enter(span2.clone())
126126
.exit(span2.clone())
127+
.enter(span2.clone())
128+
.exit(span2.clone())
127129
.drop_span(span2)
128130
.exit(span.clone())
129131
.enter(span.clone())
@@ -207,13 +209,17 @@ fn async_fn_with_async_trait() {
207209
.exit(span3.clone())
208210
.enter(span3.clone())
209211
.exit(span3.clone())
212+
.enter(span3.clone())
213+
.exit(span3.clone())
210214
.drop_span(span3)
211215
.new_span(span2.clone().with_fields(expect::field("self")))
212216
.enter(span2.clone())
213217
.event(expect::event().with_fields(expect::field("val").with_value(&5u64)))
214218
.exit(span2.clone())
215219
.enter(span2.clone())
216220
.exit(span2.clone())
221+
.enter(span2.clone())
222+
.exit(span2.clone())
217223
.drop_span(span2)
218224
.exit(span.clone())
219225
.enter(span.clone())

tracing-attributes/tests/err.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ fn test_async() {
8181
.exit(span.clone())
8282
.enter(span.clone())
8383
.exit(span.clone())
84+
.enter(span.clone())
85+
.exit(span.clone())
8486
.drop_span(span)
8587
.only()
8688
.run_with_handle();
@@ -137,6 +139,8 @@ fn test_mut_async() {
137139
.exit(span.clone())
138140
.enter(span.clone())
139141
.exit(span.clone())
142+
.enter(span.clone())
143+
.exit(span.clone())
140144
.drop_span(span)
141145
.only()
142146
.run_with_handle();

tracing/src/instrument.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ use core::{
66
pin::Pin,
77
task::{Context, Poll},
88
};
9+
use core::{
10+
future::Future,
11+
marker::Sized,
12+
mem::{self, ManuallyDrop},
13+
pin::Pin,
14+
task::{Context, Poll},
15+
};
916
use pin_project_lite::pin_project;
1017

1118
#[cfg(feature = "std")]
@@ -451,14 +458,25 @@ impl<T> WithDispatch<T> {
451458

452459
/// Get a pinned mutable reference to the wrapped type.
453460
pub fn inner_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T> {
454-
self.project().inner
461+
self.project().span_and_inner_pin_mut().1
455462
}
456463

457464
/// Consumes the `Instrumented`, returning the wrapped type.
458465
///
459466
/// Note that this drops the span.
460467
pub fn into_inner(self) -> T {
461-
self.inner
468+
// To manually destructure `Instrumented` without `Drop`, we save
469+
// pointers to the fields and use `mem::forget` to leave those pointers
470+
// valid.
471+
let span: *const Span = &self.span;
472+
let inner: *const ManuallyDrop<T> = &self.inner;
473+
mem::forget(self);
474+
// SAFETY: Those pointers are valid for reads, because `Drop` didn't
475+
// run, and properly aligned, because `Instrumented` isn't
476+
// `#[repr(packed)]`.
477+
let _span = unsafe { span.read() };
478+
let inner = unsafe { inner.read() };
479+
ManuallyDrop::into_inner(inner)
462480
}
463481
}
464482

0 commit comments

Comments
 (0)