Skip to content

Commit df6720d

Browse files
committed
Consolidate tagged pointer abstractions and make them covariant
1 parent b1a7dfb commit df6720d

File tree

6 files changed

+57
-312
lines changed

6 files changed

+57
-312
lines changed

compiler/rustc_data_structures/src/marker.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ impl_dyn_send!(
7272
[Vec<T, A> where T: DynSend, A: std::alloc::Allocator + DynSend]
7373
[Box<T, A> where T: ?Sized + DynSend, A: std::alloc::Allocator + DynSend]
7474
[crate::sync::RwLock<T> where T: DynSend]
75-
[crate::tagged_ptr::CopyTaggedPtr<P, T, CP> where P: Send + crate::tagged_ptr::Pointer, T: Send + crate::tagged_ptr::Tag, const CP: bool]
75+
[crate::tagged_ptr::TaggedPtr<P, P::Target, T, CP> where P: Send + crate::tagged_ptr::Pointer<Target: Sized>, T: Send + crate::tagged_ptr::Tag, const CP: bool]
7676
[rustc_arena::TypedArena<T> where T: DynSend]
7777
[indexmap::IndexSet<V, S> where V: DynSend, S: DynSend]
7878
[indexmap::IndexMap<K, V, S> where K: DynSend, V: DynSend, S: DynSend]
@@ -148,7 +148,7 @@ impl_dyn_sync!(
148148
[crate::sync::RwLock<T> where T: DynSend + DynSync]
149149
[crate::sync::WorkerLocal<T> where T: DynSend]
150150
[crate::intern::Interned<'a, T> where 'a, T: DynSync]
151-
[crate::tagged_ptr::CopyTaggedPtr<P, T, CP> where P: Sync + crate::tagged_ptr::Pointer, T: Sync + crate::tagged_ptr::Tag, const CP: bool]
151+
[crate::tagged_ptr::TaggedPtr<P, P::Target, T, CP> where P: Sync + crate::tagged_ptr::Pointer<Target: Sized>, T: Sync + crate::tagged_ptr::Tag, const CP: bool]
152152
[parking_lot::lock_api::Mutex<R, T> where R: DynSync, T: ?Sized + DynSend]
153153
[parking_lot::lock_api::RwLock<R, T> where R: DynSync, T: ?Sized + DynSend + DynSync]
154154
[indexmap::IndexSet<V, S> where V: DynSync, S: DynSync]

compiler/rustc_data_structures/src/tagged_ptr.rs

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,10 @@ use std::sync::Arc;
2222

2323
use crate::aligned::Aligned;
2424

25-
mod copy;
26-
mod drop;
25+
mod covariant;
2726
mod impl_tag;
2827

29-
pub use copy::CopyTaggedPtr;
30-
pub use drop::TaggedPtr;
28+
pub use covariant::TaggedPtr;
3129

3230
/// This describes the pointer type encapsulated by [`TaggedPtr`] and
3331
/// [`CopyTaggedPtr`].
@@ -246,38 +244,40 @@ unsafe impl<'a, T: 'a + ?Sized + Aligned> Pointer for &'a mut T {
246244
}
247245
}
248246

249-
/// A tag type used in [`CopyTaggedPtr`] and [`TaggedPtr`] tests.
250-
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
251247
#[cfg(test)]
252-
enum Tag2 {
253-
B00 = 0b00,
254-
B01 = 0b01,
255-
B10 = 0b10,
256-
B11 = 0b11,
257-
}
248+
mod tests {
249+
use super::*;
250+
251+
/// A tag type used in [`CopyTaggedPtr`] and [`TaggedPtr`] tests.
252+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
253+
pub enum Tag2 {
254+
B00 = 0b00,
255+
B01 = 0b01,
256+
B10 = 0b10,
257+
B11 = 0b11,
258+
}
258259

259-
#[cfg(test)]
260-
unsafe impl Tag for Tag2 {
261-
const BITS: u32 = 2;
260+
unsafe impl Tag for Tag2 {
261+
const BITS: u32 = 2;
262262

263-
fn into_usize(self) -> usize {
264-
self as _
265-
}
263+
fn into_usize(self) -> usize {
264+
self as _
265+
}
266266

267-
unsafe fn from_usize(tag: usize) -> Self {
268-
match tag {
269-
0b00 => Tag2::B00,
270-
0b01 => Tag2::B01,
271-
0b10 => Tag2::B10,
272-
0b11 => Tag2::B11,
273-
_ => unreachable!(),
267+
unsafe fn from_usize(tag: usize) -> Self {
268+
match tag {
269+
0b00 => Tag2::B00,
270+
0b01 => Tag2::B01,
271+
0b10 => Tag2::B10,
272+
0b11 => Tag2::B11,
273+
_ => unreachable!(),
274+
}
274275
}
275276
}
276-
}
277277

278-
#[cfg(test)]
279-
impl<HCX> crate::stable_hasher::HashStable<HCX> for Tag2 {
280-
fn hash_stable(&self, hcx: &mut HCX, hasher: &mut crate::stable_hasher::StableHasher) {
281-
(*self as u8).hash_stable(hcx, hasher);
278+
impl<HCX> crate::stable_hasher::HashStable<HCX> for Tag2 {
279+
fn hash_stable(&self, hcx: &mut HCX, hasher: &mut crate::stable_hasher::StableHasher) {
280+
(*self as u8).hash_stable(hcx, hasher);
281+
}
282282
}
283283
}

compiler/rustc_data_structures/src/tagged_ptr/copy.rs renamed to compiler/rustc_data_structures/src/tagged_ptr/covariant.rs

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,15 @@ use std::ptr::NonNull;
99
use super::{Pointer, Tag};
1010
use crate::stable_hasher::{HashStable, StableHasher};
1111

12-
/// A [`Copy`] tagged pointer.
13-
///
14-
/// This is essentially `{ pointer: P, tag: T }` packed in a single pointer.
15-
///
16-
/// You should use this instead of the [`TaggedPtr`] type in all cases where
17-
/// `P` implements [`Copy`].
12+
/// A covariant [`Copy`] tagged pointer. This is essentially `{ pointer: P, tag: T }` packed
13+
/// in a single pointer.
1814
///
1915
/// If `COMPARE_PACKED` is true, then the pointers will be compared and hashed without
20-
/// unpacking. Otherwise we don't implement [`PartialEq`], [`Eq`] and [`Hash`];
21-
/// if you want that, wrap the [`CopyTaggedPtr`].
22-
///
23-
/// [`TaggedPtr`]: crate::tagged_ptr::TaggedPtr
24-
pub struct CopyTaggedPtr<P, T, const COMPARE_PACKED: bool>
16+
/// unpacking. Otherwise we don't implement [`PartialEq`], [`Eq`] and [`Hash`]; if you
17+
/// want that, wrap the [`TaggedPtr`].
18+
pub struct TaggedPtr<P, Pointee: ?Sized, T, const COMPARE_PACKED: bool>
2519
where
26-
P: Pointer,
20+
P: Pointer<Target = Pointee>,
2721
T: Tag,
2822
{
2923
/// This is semantically a pair of `pointer: P` and `tag: T` fields,
@@ -64,14 +58,14 @@ where
6458
///
6559
/// The tag can be retrieved by `packed.addr() >> T::BITS` and the pointer
6660
/// can be retrieved by `packed.map_addr(|addr| addr << T::BITS)`.
67-
packed: NonNull<P::Target>,
68-
tag_ghost: PhantomData<T>,
61+
packed: NonNull<Pointee>,
62+
tag_pointer_ghost: PhantomData<(P, T)>,
6963
}
7064

7165
// Note that even though `CopyTaggedPtr` is only really expected to work with
7266
// `P: Copy`, can't add `P: Copy` bound, because `CopyTaggedPtr` is used in the
7367
// `TaggedPtr`'s implementation.
74-
impl<P, T, const CP: bool> CopyTaggedPtr<P, T, CP>
68+
impl<P, T, const CP: bool> TaggedPtr<P, P::Target, T, CP>
7569
where
7670
P: Pointer,
7771
T: Tag,
@@ -85,7 +79,7 @@ where
8579
/// [`TaggedPtr`]: crate::tagged_ptr::TaggedPtr
8680
#[inline]
8781
pub fn new(pointer: P, tag: T) -> Self {
88-
Self { packed: Self::pack(P::into_ptr(pointer), tag), tag_ghost: PhantomData }
82+
Self { packed: Self::pack(P::into_ptr(pointer), tag), tag_pointer_ghost: PhantomData }
8983
}
9084

9185
/// Retrieves the pointer.
@@ -177,14 +171,14 @@ where
177171
}
178172
}
179173

180-
impl<P, T, const CP: bool> Copy for CopyTaggedPtr<P, T, CP>
174+
impl<P, T, const CP: bool> Copy for TaggedPtr<P, P::Target, T, CP>
181175
where
182176
P: Pointer + Copy,
183177
T: Tag,
184178
{
185179
}
186180

187-
impl<P, T, const CP: bool> Clone for CopyTaggedPtr<P, T, CP>
181+
impl<P, T, const CP: bool> Clone for TaggedPtr<P, P::Target, T, CP>
188182
where
189183
P: Pointer + Copy,
190184
T: Tag,
@@ -195,7 +189,7 @@ where
195189
}
196190
}
197191

198-
impl<P, T, const CP: bool> Deref for CopyTaggedPtr<P, T, CP>
192+
impl<P, T, const CP: bool> Deref for TaggedPtr<P, P::Target, T, CP>
199193
where
200194
P: Pointer,
201195
T: Tag,
@@ -211,7 +205,7 @@ where
211205
}
212206
}
213207

214-
impl<P, T, const CP: bool> DerefMut for CopyTaggedPtr<P, T, CP>
208+
impl<P, T, const CP: bool> DerefMut for TaggedPtr<P, P::Target, T, CP>
215209
where
216210
P: Pointer + DerefMut,
217211
T: Tag,
@@ -226,7 +220,7 @@ where
226220
}
227221
}
228222

229-
impl<P, T, const CP: bool> fmt::Debug for CopyTaggedPtr<P, T, CP>
223+
impl<P, T, const CP: bool> fmt::Debug for TaggedPtr<P, P::Target, T, CP>
230224
where
231225
P: Pointer + fmt::Debug,
232226
T: Tag + fmt::Debug,
@@ -238,7 +232,7 @@ where
238232
}
239233
}
240234

241-
impl<P, T> PartialEq for CopyTaggedPtr<P, T, true>
235+
impl<P, T> PartialEq for TaggedPtr<P, P::Target, T, true>
242236
where
243237
P: Pointer,
244238
T: Tag,
@@ -250,14 +244,14 @@ where
250244
}
251245
}
252246

253-
impl<P, T> Eq for CopyTaggedPtr<P, T, true>
247+
impl<P, T> Eq for TaggedPtr<P, P::Target, T, true>
254248
where
255249
P: Pointer,
256250
T: Tag,
257251
{
258252
}
259253

260-
impl<P, T> Hash for CopyTaggedPtr<P, T, true>
254+
impl<P, T> Hash for TaggedPtr<P, P::Target, T, true>
261255
where
262256
P: Pointer,
263257
T: Tag,
@@ -268,7 +262,7 @@ where
268262
}
269263
}
270264

271-
impl<P, T, HCX, const CP: bool> HashStable<HCX> for CopyTaggedPtr<P, T, CP>
265+
impl<P, T, HCX, const CP: bool> HashStable<HCX> for TaggedPtr<P, P::Target, T, CP>
272266
where
273267
P: Pointer + HashStable<HCX>,
274268
T: Tag + HashStable<HCX>,
@@ -282,7 +276,7 @@ where
282276
// Safety:
283277
// `CopyTaggedPtr<P, T, ..>` is semantically just `{ ptr: P, tag: T }`, as such
284278
// it's ok to implement `Sync` as long as `P: Sync, T: Sync`
285-
unsafe impl<P, T, const CP: bool> Sync for CopyTaggedPtr<P, T, CP>
279+
unsafe impl<P, T, const CP: bool> Sync for TaggedPtr<P, P::Target, T, CP>
286280
where
287281
P: Sync + Pointer,
288282
T: Sync + Tag,
@@ -292,7 +286,7 @@ where
292286
// Safety:
293287
// `CopyTaggedPtr<P, T, ..>` is semantically just `{ ptr: P, tag: T }`, as such
294288
// it's ok to implement `Send` as long as `P: Send, T: Send`
295-
unsafe impl<P, T, const CP: bool> Send for CopyTaggedPtr<P, T, CP>
289+
unsafe impl<P, T, const CP: bool> Send for TaggedPtr<P, P::Target, T, CP>
296290
where
297291
P: Send + Pointer,
298292
T: Send + Tag,

compiler/rustc_data_structures/src/tagged_ptr/copy/tests.rs renamed to compiler/rustc_data_structures/src/tagged_ptr/covariant/tests.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use std::ptr;
22

3+
use super::*;
34
use crate::hashes::Hash128;
45
use crate::stable_hasher::{HashStable, StableHasher};
5-
use crate::tagged_ptr::{CopyTaggedPtr, Pointer, Tag, Tag2};
6+
use crate::tagged_ptr::tests::Tag2;
67

78
#[test]
89
fn smoke() {
@@ -45,6 +46,6 @@ fn stable_hash_hashes_as_tuple() {
4546
}
4647

4748
/// Helper to create tagged pointers without specifying `COMPARE_PACKED` if it does not matter.
48-
fn tag_ptr<P: Pointer, T: Tag>(ptr: P, tag: T) -> CopyTaggedPtr<P, T, true> {
49-
CopyTaggedPtr::new(ptr, tag)
49+
fn tag_ptr<P: Pointer, T: Tag>(ptr: P, tag: T) -> TaggedPtr<P, P::Target, T, true> {
50+
TaggedPtr::new(ptr, tag)
5051
}

0 commit comments

Comments
 (0)