Skip to content

Commit 1e39283

Browse files
authored
Remove object lifetime cast (#564)
1 parent 2f370a1 commit 1e39283

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

metrics/src/recorder/mod.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,19 @@ pub struct LocalRecorderGuard<'a> {
139139

140140
impl<'a> LocalRecorderGuard<'a> {
141141
/// Creates a new `LocalRecorderGuard` and sets the thread-local recorder.
142-
fn new(recorder: &'a dyn Recorder) -> Self {
142+
fn new(recorder: &'a (dyn Recorder + 'a)) -> Self {
143+
// SAFETY: We extend `'a` to `'static` to satisfy the signature of `LOCAL_RECORDER`, which
144+
// has an implied `'static` bound on `dyn Recorder`. We enforce that all usages of `LOCAL_RECORDER`
145+
// are limited to `'a` as we mediate its access entirely through `LocalRecorderGuard<'a>`.
146+
let recorder_ptr = unsafe {
147+
std::mem::transmute::<*const (dyn Recorder + 'a), *mut (dyn Recorder + 'static)>(
148+
recorder as &'a (dyn Recorder + 'a),
149+
)
150+
};
143151
// SAFETY: While we take a lifetime-less pointer to the given reference, the reference we derive _from_ the
144152
// pointer is given the same lifetime of the reference used to construct the guard -- captured in the guard type
145153
// itself -- and so derived references never outlive the source reference.
146-
let recorder_ptr = unsafe { NonNull::new_unchecked(recorder as *const _ as *mut _) };
154+
let recorder_ptr = unsafe { NonNull::new_unchecked(recorder_ptr) };
147155

148156
let prev_recorder =
149157
LOCAL_RECORDER.with(|local_recorder| local_recorder.replace(Some(recorder_ptr)));

0 commit comments

Comments
 (0)