Skip to content

Remove object lifetime cast #564

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 31, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions metrics/src/recorder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,19 @@ pub struct LocalRecorderGuard<'a> {

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

let prev_recorder =
LOCAL_RECORDER.with(|local_recorder| local_recorder.replace(Some(recorder_ptr)));
Expand Down