]>
Commit | Line | Data |
---|---|---|
dc9dc135 | 1 | use crate::convert::From; |
dc9dc135 XL |
2 | use crate::fmt; |
3 | use crate::marker::{PhantomData, Unsize}; | |
4 | use crate::mem; | |
60c5eb7d | 5 | use crate::ops::{CoerceUnsized, DispatchFromDyn}; |
dc9dc135 XL |
6 | use crate::ptr::NonNull; |
7 | ||
60c5eb7d XL |
8 | // ignore-tidy-undocumented-unsafe |
9 | ||
dc9dc135 XL |
10 | /// A wrapper around a raw non-null `*mut T` that indicates that the possessor |
11 | /// of this wrapper owns the referent. Useful for building abstractions like | |
12 | /// `Box<T>`, `Vec<T>`, `String`, and `HashMap<K, V>`. | |
13 | /// | |
14 | /// Unlike `*mut T`, `Unique<T>` behaves "as if" it were an instance of `T`. | |
15 | /// It implements `Send`/`Sync` if `T` is `Send`/`Sync`. It also implies | |
16 | /// the kind of strong aliasing guarantees an instance of `T` can expect: | |
17 | /// the referent of the pointer should not be modified without a unique path to | |
18 | /// its owning Unique. | |
19 | /// | |
20 | /// If you're uncertain of whether it's correct to use `Unique` for your purposes, | |
21 | /// consider using `NonNull`, which has weaker semantics. | |
22 | /// | |
23 | /// Unlike `*mut T`, the pointer must always be non-null, even if the pointer | |
24 | /// is never dereferenced. This is so that enums may use this forbidden value | |
25 | /// as a discriminant -- `Option<Unique<T>>` has the same size as `Unique<T>`. | |
26 | /// However the pointer may still dangle if it isn't dereferenced. | |
27 | /// | |
28 | /// Unlike `*mut T`, `Unique<T>` is covariant over `T`. This should always be correct | |
29 | /// for any type which upholds Unique's aliasing requirements. | |
60c5eb7d XL |
30 | #[unstable( |
31 | feature = "ptr_internals", | |
dfeec247 | 32 | issue = "none", |
60c5eb7d XL |
33 | reason = "use `NonNull` instead and consider `PhantomData<T>` \ |
34 | (if you also use `#[may_dangle]`), `Send`, and/or `Sync`" | |
35 | )] | |
dc9dc135 XL |
36 | #[doc(hidden)] |
37 | #[repr(transparent)] | |
38 | #[rustc_layout_scalar_valid_range_start(1)] | |
39 | pub struct Unique<T: ?Sized> { | |
40 | pointer: *const T, | |
41 | // NOTE: this marker has no consequences for variance, but is necessary | |
42 | // for dropck to understand that we logically own a `T`. | |
43 | // | |
44 | // For details, see: | |
45 | // https://github.com/rust-lang/rfcs/blob/master/text/0769-sound-generic-drop.md#phantom-data | |
46 | _marker: PhantomData<T>, | |
47 | } | |
48 | ||
49 | /// `Unique` pointers are `Send` if `T` is `Send` because the data they | |
50 | /// reference is unaliased. Note that this aliasing invariant is | |
51 | /// unenforced by the type system; the abstraction using the | |
52 | /// `Unique` must enforce it. | |
dfeec247 | 53 | #[unstable(feature = "ptr_internals", issue = "none")] |
60c5eb7d | 54 | unsafe impl<T: Send + ?Sized> Send for Unique<T> {} |
dc9dc135 XL |
55 | |
56 | /// `Unique` pointers are `Sync` if `T` is `Sync` because the data they | |
57 | /// reference is unaliased. Note that this aliasing invariant is | |
58 | /// unenforced by the type system; the abstraction using the | |
59 | /// `Unique` must enforce it. | |
dfeec247 | 60 | #[unstable(feature = "ptr_internals", issue = "none")] |
60c5eb7d | 61 | unsafe impl<T: Sync + ?Sized> Sync for Unique<T> {} |
dc9dc135 | 62 | |
dfeec247 | 63 | #[unstable(feature = "ptr_internals", issue = "none")] |
dc9dc135 XL |
64 | impl<T: Sized> Unique<T> { |
65 | /// Creates a new `Unique` that is dangling, but well-aligned. | |
66 | /// | |
67 | /// This is useful for initializing types which lazily allocate, like | |
68 | /// `Vec::new` does. | |
69 | /// | |
70 | /// Note that the pointer value may potentially represent a valid pointer to | |
71 | /// a `T`, which means this must not be used as a "not yet initialized" | |
72 | /// sentinel value. Types that lazily allocate must track initialization by | |
73 | /// some other means. | |
74 | // FIXME: rename to dangling() to match NonNull? | |
75 | #[inline] | |
76 | pub const fn empty() -> Self { | |
60c5eb7d | 77 | unsafe { Unique::new_unchecked(mem::align_of::<T>() as *mut T) } |
dc9dc135 XL |
78 | } |
79 | } | |
80 | ||
dfeec247 | 81 | #[unstable(feature = "ptr_internals", issue = "none")] |
dc9dc135 XL |
82 | impl<T: ?Sized> Unique<T> { |
83 | /// Creates a new `Unique`. | |
84 | /// | |
85 | /// # Safety | |
86 | /// | |
87 | /// `ptr` must be non-null. | |
88 | #[inline] | |
89 | pub const unsafe fn new_unchecked(ptr: *mut T) -> Self { | |
90 | Unique { pointer: ptr as _, _marker: PhantomData } | |
91 | } | |
92 | ||
93 | /// Creates a new `Unique` if `ptr` is non-null. | |
94 | #[inline] | |
95 | pub fn new(ptr: *mut T) -> Option<Self> { | |
96 | if !ptr.is_null() { | |
97 | Some(unsafe { Unique { pointer: ptr as _, _marker: PhantomData } }) | |
98 | } else { | |
99 | None | |
100 | } | |
101 | } | |
102 | ||
103 | /// Acquires the underlying `*mut` pointer. | |
104 | #[inline] | |
105 | pub const fn as_ptr(self) -> *mut T { | |
106 | self.pointer as *mut T | |
107 | } | |
108 | ||
109 | /// Dereferences the content. | |
110 | /// | |
111 | /// The resulting lifetime is bound to self so this behaves "as if" | |
112 | /// it were actually an instance of T that is getting borrowed. If a longer | |
113 | /// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`. | |
114 | #[inline] | |
115 | pub unsafe fn as_ref(&self) -> &T { | |
116 | &*self.as_ptr() | |
117 | } | |
118 | ||
119 | /// Mutably dereferences the content. | |
120 | /// | |
121 | /// The resulting lifetime is bound to self so this behaves "as if" | |
122 | /// it were actually an instance of T that is getting borrowed. If a longer | |
123 | /// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`. | |
124 | #[inline] | |
125 | pub unsafe fn as_mut(&mut self) -> &mut T { | |
126 | &mut *self.as_ptr() | |
127 | } | |
e1599b0c XL |
128 | |
129 | /// Casts to a pointer of another type. | |
130 | #[inline] | |
131 | pub const fn cast<U>(self) -> Unique<U> { | |
60c5eb7d | 132 | unsafe { Unique::new_unchecked(self.as_ptr() as *mut U) } |
e1599b0c | 133 | } |
dc9dc135 XL |
134 | } |
135 | ||
dfeec247 | 136 | #[unstable(feature = "ptr_internals", issue = "none")] |
dc9dc135 XL |
137 | impl<T: ?Sized> Clone for Unique<T> { |
138 | #[inline] | |
139 | fn clone(&self) -> Self { | |
140 | *self | |
141 | } | |
142 | } | |
143 | ||
dfeec247 | 144 | #[unstable(feature = "ptr_internals", issue = "none")] |
60c5eb7d | 145 | impl<T: ?Sized> Copy for Unique<T> {} |
dc9dc135 | 146 | |
dfeec247 | 147 | #[unstable(feature = "ptr_internals", issue = "none")] |
60c5eb7d | 148 | impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {} |
dc9dc135 | 149 | |
dfeec247 | 150 | #[unstable(feature = "ptr_internals", issue = "none")] |
60c5eb7d | 151 | impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> {} |
dc9dc135 | 152 | |
dfeec247 | 153 | #[unstable(feature = "ptr_internals", issue = "none")] |
dc9dc135 XL |
154 | impl<T: ?Sized> fmt::Debug for Unique<T> { |
155 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
156 | fmt::Pointer::fmt(&self.as_ptr(), f) | |
157 | } | |
158 | } | |
159 | ||
dfeec247 | 160 | #[unstable(feature = "ptr_internals", issue = "none")] |
dc9dc135 XL |
161 | impl<T: ?Sized> fmt::Pointer for Unique<T> { |
162 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
163 | fmt::Pointer::fmt(&self.as_ptr(), f) | |
164 | } | |
165 | } | |
166 | ||
dfeec247 | 167 | #[unstable(feature = "ptr_internals", issue = "none")] |
dc9dc135 XL |
168 | impl<T: ?Sized> From<&mut T> for Unique<T> { |
169 | #[inline] | |
170 | fn from(reference: &mut T) -> Self { | |
171 | unsafe { Unique { pointer: reference as *mut T, _marker: PhantomData } } | |
172 | } | |
173 | } | |
174 | ||
dfeec247 | 175 | #[unstable(feature = "ptr_internals", issue = "none")] |
dc9dc135 XL |
176 | impl<T: ?Sized> From<&T> for Unique<T> { |
177 | #[inline] | |
178 | fn from(reference: &T) -> Self { | |
179 | unsafe { Unique { pointer: reference as *const T, _marker: PhantomData } } | |
180 | } | |
181 | } | |
182 | ||
dfeec247 | 183 | #[unstable(feature = "ptr_internals", issue = "none")] |
416331ca | 184 | impl<T: ?Sized> From<NonNull<T>> for Unique<T> { |
dc9dc135 XL |
185 | #[inline] |
186 | fn from(p: NonNull<T>) -> Self { | |
187 | unsafe { Unique::new_unchecked(p.as_ptr()) } | |
188 | } | |
189 | } |