Skip to content

Commit cdd0676

Browse files
BoxyUwUtobz
authored andcommitted
Remove object lifetime cast (#564)
1 parent ee2f7de commit cdd0676

File tree

1 file changed

+16
-9
lines changed

1 file changed

+16
-9
lines changed

metrics/src/recorder/mod.rs

+16-9
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,19 @@ pub struct LocalRecorderGuard<'a> {
7979

8080
impl<'a> LocalRecorderGuard<'a> {
8181
/// Creates a new `LocalRecorderGuard` and sets the thread-local recorder.
82-
fn new(recorder: &'a dyn Recorder) -> Self {
83-
// SAFETY: While we take a lifetime-less pointer to the given reference, the reference we
84-
// derive _from_ the pointer is given the same lifetime of the reference
85-
// used to construct the guard -- captured in the guard type itself --
86-
// and so derived references never outlive the source reference.
87-
let recorder_ptr = unsafe { NonNull::new_unchecked(recorder as *const _ as *mut _) };
82+
fn new(recorder: &'a (dyn Recorder + 'a)) -> Self {
83+
// SAFETY: We extend `'a` to `'static` to satisfy the signature of `LOCAL_RECORDER`, which
84+
// has an implied `'static` bound on `dyn Recorder`. We enforce that all usages of `LOCAL_RECORDER`
85+
// are limited to `'a` as we mediate its access entirely through `LocalRecorderGuard<'a>`.
86+
let recorder_ptr = unsafe {
87+
std::mem::transmute::<*const (dyn Recorder + 'a), *mut (dyn Recorder + 'static)>(
88+
recorder as &'a (dyn Recorder + 'a),
89+
)
90+
};
91+
// SAFETY: While we take a lifetime-less pointer to the given reference, the reference we derive _from_ the
92+
// pointer is given the same lifetime of the reference used to construct the guard -- captured in the guard type
93+
// itself -- and so derived references never outlive the source reference.
94+
let recorder_ptr = unsafe { NonNull::new_unchecked(recorder_ptr) };
8895

8996
let prev_recorder =
9097
LOCAL_RECORDER.with(|local_recorder| local_recorder.replace(Some(recorder_ptr)));
@@ -177,11 +184,11 @@ pub fn with_recorder<T>(f: impl FnOnce(&dyn Recorder) -> T) -> T {
177184

178185
#[cfg(test)]
179186
mod tests {
180-
use std::sync::{atomic::Ordering, Arc};
187+
use std::sync::atomic::Ordering;
181188

182-
use crate::{with_local_recorder, NoopRecorder};
189+
use crate::with_local_recorder;
183190

184-
use super::{Recorder, RecorderOnceCell};
191+
use super::RecorderOnceCell;
185192

186193
#[test]
187194
fn boxed_recorder_dropped_on_existing_set() {

0 commit comments

Comments
 (0)