Skip to content

Commit c6acd5c

Browse files
committed
Remove Pointer::with_ref in favour implementing it on tagged pointers directly
1 parent 9051331 commit c6acd5c

File tree

3 files changed

+25
-40
lines changed

3 files changed

+25
-40
lines changed

compiler/rustc_data_structures/src/tagged_ptr.rs

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
//! The tag must implement the `Tag` trait. We assert that the tag and `Pointer`
1414
//! are compatible at compile time.
1515
16-
use std::mem::ManuallyDrop;
1716
use std::ops::Deref;
1817
use std::ptr::NonNull;
1918
use std::rc::Rc;
@@ -81,16 +80,6 @@ pub unsafe trait Pointer: Deref {
8180
/// This acts as `ptr::read` semantically, it should not be called more than
8281
/// once on non-`Copy` `Pointer`s.
8382
unsafe fn from_ptr(ptr: NonNull<Self::Target>) -> Self;
84-
85-
/// This provides a reference to the `Pointer` itself, rather than the
86-
/// `Deref::Target`. It is used for cases where we want to call methods that
87-
/// may be implement differently for the Pointer than the Pointee (e.g.,
88-
/// `Rc::clone` vs cloning the inner value).
89-
///
90-
/// # Safety
91-
///
92-
/// The passed `ptr` must be returned from `into_usize`.
93-
unsafe fn with_ref<R, F: FnOnce(&Self) -> R>(ptr: NonNull<Self::Target>, f: F) -> R;
9483
}
9584

9685
/// This describes tags that the `TaggedPtr` struct can hold.
@@ -124,11 +113,6 @@ unsafe impl<T: ?Sized + Aligned> Pointer for Box<T> {
124113
unsafe fn from_ptr(ptr: NonNull<T>) -> Self {
125114
Box::from_raw(ptr.as_ptr())
126115
}
127-
128-
unsafe fn with_ref<R, F: FnOnce(&Self) -> R>(ptr: NonNull<T>, f: F) -> R {
129-
let raw = ManuallyDrop::new(Self::from_ptr(ptr));
130-
f(&raw)
131-
}
132116
}
133117

134118
unsafe impl<T: ?Sized + Aligned> Pointer for Rc<T> {
@@ -143,11 +127,6 @@ unsafe impl<T: ?Sized + Aligned> Pointer for Rc<T> {
143127
unsafe fn from_ptr(ptr: NonNull<T>) -> Self {
144128
Rc::from_raw(ptr.as_ptr())
145129
}
146-
147-
unsafe fn with_ref<R, F: FnOnce(&Self) -> R>(ptr: NonNull<T>, f: F) -> R {
148-
let raw = ManuallyDrop::new(Self::from_ptr(ptr));
149-
f(&raw)
150-
}
151130
}
152131

153132
unsafe impl<T: ?Sized + Aligned> Pointer for Arc<T> {
@@ -162,11 +141,6 @@ unsafe impl<T: ?Sized + Aligned> Pointer for Arc<T> {
162141
unsafe fn from_ptr(ptr: NonNull<T>) -> Self {
163142
Arc::from_raw(ptr.as_ptr())
164143
}
165-
166-
unsafe fn with_ref<R, F: FnOnce(&Self) -> R>(ptr: NonNull<T>, f: F) -> R {
167-
let raw = ManuallyDrop::new(Self::from_ptr(ptr));
168-
f(&raw)
169-
}
170144
}
171145

172146
unsafe impl<'a, T: 'a + ?Sized + Aligned> Pointer for &'a T {
@@ -181,10 +155,6 @@ unsafe impl<'a, T: 'a + ?Sized + Aligned> Pointer for &'a T {
181155
unsafe fn from_ptr(ptr: NonNull<T>) -> Self {
182156
ptr.as_ref()
183157
}
184-
185-
unsafe fn with_ref<R, F: FnOnce(&Self) -> R>(ptr: NonNull<T>, f: F) -> R {
186-
f(&ptr.as_ref())
187-
}
188158
}
189159

190160
unsafe impl<'a, T: 'a + ?Sized + Aligned> Pointer for &'a mut T {
@@ -199,10 +169,6 @@ unsafe impl<'a, T: 'a + ?Sized + Aligned> Pointer for &'a mut T {
199169
unsafe fn from_ptr(mut ptr: NonNull<T>) -> Self {
200170
ptr.as_mut()
201171
}
202-
203-
unsafe fn with_ref<R, F: FnOnce(&Self) -> R>(mut ptr: NonNull<T>, f: F) -> R {
204-
f(&ptr.as_mut())
205-
}
206172
}
207173

208174
/// Returns the number of bits available for use for tags in a pointer to `T`

compiler/rustc_data_structures/src/tagged_ptr/copy.rs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use super::{Pointer, Tag};
22
use crate::stable_hasher::{HashStable, StableHasher};
33
use std::fmt;
44
use std::marker::PhantomData;
5+
use std::mem::ManuallyDrop;
56
use std::num::NonZeroUsize;
67
use std::ops::{Deref, DerefMut};
78
use std::ptr::NonNull;
@@ -85,6 +86,24 @@ where
8586
self.packed.map_addr(|addr| unsafe { NonZeroUsize::new_unchecked(addr.get() << T::BITS) })
8687
}
8788

89+
/// This provides a reference to the `P` pointer itself, rather than the
90+
/// `Deref::Target`. It is used for cases where we want to call methods
91+
/// that may be implement differently for the Pointer than the Pointee
92+
/// (e.g., `Rc::clone` vs cloning the inner value).
93+
pub(super) fn with_pointer_ref<R>(&self, f: impl FnOnce(&P) -> R) -> R {
94+
// Safety:
95+
// - `self.raw.pointer_raw()` is originally returned from `P::into_ptr`
96+
// and as such is valid for `P::from_ptr`.
97+
// - This also allows us to not care whatever `f` panics or not.
98+
// - Even though we create a copy of the pointer, we store it inside
99+
// `ManuallyDrop` and only access it by-ref, so we don't double-drop.
100+
//
101+
// Semantically this is just `f(&self.pointer)` (where `self.pointer`
102+
// is non-packed original pointer).
103+
let ptr = unsafe { ManuallyDrop::new(P::from_ptr(self.pointer_raw())) };
104+
f(&ptr)
105+
}
106+
88107
pub fn pointer(self) -> P
89108
where
90109
P: Copy,
@@ -189,9 +208,7 @@ where
189208
T: Tag + HashStable<HCX>,
190209
{
191210
fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) {
192-
unsafe {
193-
Pointer::with_ref(self.pointer_raw(), |p: &P| p.hash_stable(hcx, hasher));
194-
}
211+
self.with_pointer_ref(|ptr| ptr.hash_stable(hcx, hasher));
195212
self.tag().hash_stable(hcx, hasher);
196213
}
197214
}

compiler/rustc_data_structures/src/tagged_ptr/drop.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use super::{Pointer, Tag};
2-
use crate::stable_hasher::{HashStable, StableHasher};
31
use std::fmt;
42

53
use super::CopyTaggedPtr;
4+
use super::{Pointer, Tag};
5+
use crate::stable_hasher::{HashStable, StableHasher};
66

77
/// A TaggedPtr implementing `Drop`.
88
///
@@ -23,7 +23,9 @@ where
2323
T: Tag,
2424
{
2525
fn clone(&self) -> Self {
26-
unsafe { Self::new(P::with_ref(self.raw.pointer_raw(), |p| p.clone()), self.raw.tag()) }
26+
let ptr = self.raw.with_pointer_ref(P::clone);
27+
28+
Self::new(ptr, self.tag())
2729
}
2830
}
2931

0 commit comments

Comments
 (0)