Skip to content

Commit 7212685

Browse files
committed
Auto merge of #61274 - Centril:rollup-23dekk4, r=Centril
Rollup of 4 pull requests Successful merges: - #61123 (Allow to specify profiling data output directory as -Zself-profile argument.) - #61159 (split core::ptr module into multiple files) - #61164 (rename Scalar::Bits to Scalar::Raw and bits field to data) - #61250 (Remove special case for *ios* builds in run-make-fulldeps/print-target-list Makefile) Failed merges: r? @ghost
2 parents a6ce9b3 + e06547f commit 7212685

File tree

29 files changed

+645
-618
lines changed

29 files changed

+645
-618
lines changed

src/libcore/ptr.rs renamed to src/libcore/ptr/mod.rs

+8-387
Large diffs are not rendered by default.

src/libcore/ptr/non_null.rs

+226
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
use crate::convert::From;
2+
use crate::ops::{CoerceUnsized, DispatchFromDyn};
3+
use crate::fmt;
4+
use crate::hash;
5+
use crate::marker::Unsize;
6+
use crate::mem;
7+
use crate::ptr::Unique;
8+
use crate::cmp::Ordering;
9+
10+
/// `*mut T` but non-zero and covariant.
11+
///
12+
/// This is often the correct thing to use when building data structures using
13+
/// raw pointers, but is ultimately more dangerous to use because of its additional
14+
/// properties. If you're not sure if you should use `NonNull<T>`, just use `*mut T`!
15+
///
16+
/// Unlike `*mut T`, the pointer must always be non-null, even if the pointer
17+
/// is never dereferenced. This is so that enums may use this forbidden value
18+
/// as a discriminant -- `Option<NonNull<T>>` has the same size as `*mut T`.
19+
/// However the pointer may still dangle if it isn't dereferenced.
20+
///
21+
/// Unlike `*mut T`, `NonNull<T>` is covariant over `T`. If this is incorrect
22+
/// for your use case, you should include some [`PhantomData`] in your type to
23+
/// provide invariance, such as `PhantomData<Cell<T>>` or `PhantomData<&'a mut T>`.
24+
/// Usually this won't be necessary; covariance is correct for most safe abstractions,
25+
/// such as `Box`, `Rc`, `Arc`, `Vec`, and `LinkedList`. This is the case because they
26+
/// provide a public API that follows the normal shared XOR mutable rules of Rust.
27+
///
28+
/// Notice that `NonNull<T>` has a `From` instance for `&T`. However, this does
29+
/// not change the fact that mutating through a (pointer derived from a) shared
30+
/// reference is undefined behavior unless the mutation happens inside an
31+
/// [`UnsafeCell<T>`]. The same goes for creating a mutable reference from a shared
32+
/// reference. When using this `From` instance without an `UnsafeCell<T>`,
33+
/// it is your responsibility to ensure that `as_mut` is never called, and `as_ptr`
34+
/// is never used for mutation.
35+
///
36+
/// [`PhantomData`]: ../marker/struct.PhantomData.html
37+
/// [`UnsafeCell<T>`]: ../cell/struct.UnsafeCell.html
38+
#[stable(feature = "nonnull", since = "1.25.0")]
39+
#[repr(transparent)]
40+
#[rustc_layout_scalar_valid_range_start(1)]
41+
#[cfg_attr(not(stage0), rustc_nonnull_optimization_guaranteed)]
42+
pub struct NonNull<T: ?Sized> {
43+
pointer: *const T,
44+
}
45+
46+
/// `NonNull` pointers are not `Send` because the data they reference may be aliased.
47+
// N.B., this impl is unnecessary, but should provide better error messages.
48+
#[stable(feature = "nonnull", since = "1.25.0")]
49+
impl<T: ?Sized> !Send for NonNull<T> { }
50+
51+
/// `NonNull` pointers are not `Sync` because the data they reference may be aliased.
52+
// N.B., this impl is unnecessary, but should provide better error messages.
53+
#[stable(feature = "nonnull", since = "1.25.0")]
54+
impl<T: ?Sized> !Sync for NonNull<T> { }
55+
56+
impl<T: Sized> NonNull<T> {
57+
/// Creates a new `NonNull` that is dangling, but well-aligned.
58+
///
59+
/// This is useful for initializing types which lazily allocate, like
60+
/// `Vec::new` does.
61+
///
62+
/// Note that the pointer value may potentially represent a valid pointer to
63+
/// a `T`, which means this must not be used as a "not yet initialized"
64+
/// sentinel value. Types that lazily allocate must track initialization by
65+
/// some other means.
66+
#[stable(feature = "nonnull", since = "1.25.0")]
67+
#[inline]
68+
pub const fn dangling() -> Self {
69+
unsafe {
70+
let ptr = mem::align_of::<T>() as *mut T;
71+
NonNull::new_unchecked(ptr)
72+
}
73+
}
74+
}
75+
76+
impl<T: ?Sized> NonNull<T> {
77+
/// Creates a new `NonNull`.
78+
///
79+
/// # Safety
80+
///
81+
/// `ptr` must be non-null.
82+
#[stable(feature = "nonnull", since = "1.25.0")]
83+
#[inline]
84+
pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
85+
NonNull { pointer: ptr as _ }
86+
}
87+
88+
/// Creates a new `NonNull` if `ptr` is non-null.
89+
#[stable(feature = "nonnull", since = "1.25.0")]
90+
#[inline]
91+
pub fn new(ptr: *mut T) -> Option<Self> {
92+
if !ptr.is_null() {
93+
Some(unsafe { Self::new_unchecked(ptr) })
94+
} else {
95+
None
96+
}
97+
}
98+
99+
/// Acquires the underlying `*mut` pointer.
100+
#[stable(feature = "nonnull", since = "1.25.0")]
101+
#[inline]
102+
pub const fn as_ptr(self) -> *mut T {
103+
self.pointer as *mut T
104+
}
105+
106+
/// Dereferences the content.
107+
///
108+
/// The resulting lifetime is bound to self so this behaves "as if"
109+
/// it were actually an instance of T that is getting borrowed. If a longer
110+
/// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`.
111+
#[stable(feature = "nonnull", since = "1.25.0")]
112+
#[inline]
113+
pub unsafe fn as_ref(&self) -> &T {
114+
&*self.as_ptr()
115+
}
116+
117+
/// Mutably dereferences the content.
118+
///
119+
/// The resulting lifetime is bound to self so this behaves "as if"
120+
/// it were actually an instance of T that is getting borrowed. If a longer
121+
/// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`.
122+
#[stable(feature = "nonnull", since = "1.25.0")]
123+
#[inline]
124+
pub unsafe fn as_mut(&mut self) -> &mut T {
125+
&mut *self.as_ptr()
126+
}
127+
128+
/// Cast to a pointer of another type
129+
#[stable(feature = "nonnull_cast", since = "1.27.0")]
130+
#[inline]
131+
pub const fn cast<U>(self) -> NonNull<U> {
132+
unsafe {
133+
NonNull::new_unchecked(self.as_ptr() as *mut U)
134+
}
135+
}
136+
}
137+
138+
#[stable(feature = "nonnull", since = "1.25.0")]
139+
impl<T: ?Sized> Clone for NonNull<T> {
140+
#[inline]
141+
fn clone(&self) -> Self {
142+
*self
143+
}
144+
}
145+
146+
#[stable(feature = "nonnull", since = "1.25.0")]
147+
impl<T: ?Sized> Copy for NonNull<T> { }
148+
149+
#[unstable(feature = "coerce_unsized", issue = "27732")]
150+
impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> { }
151+
152+
#[unstable(feature = "dispatch_from_dyn", issue = "0")]
153+
impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: Unsize<U> { }
154+
155+
#[stable(feature = "nonnull", since = "1.25.0")]
156+
impl<T: ?Sized> fmt::Debug for NonNull<T> {
157+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
158+
fmt::Pointer::fmt(&self.as_ptr(), f)
159+
}
160+
}
161+
162+
#[stable(feature = "nonnull", since = "1.25.0")]
163+
impl<T: ?Sized> fmt::Pointer for NonNull<T> {
164+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
165+
fmt::Pointer::fmt(&self.as_ptr(), f)
166+
}
167+
}
168+
169+
#[stable(feature = "nonnull", since = "1.25.0")]
170+
impl<T: ?Sized> Eq for NonNull<T> {}
171+
172+
#[stable(feature = "nonnull", since = "1.25.0")]
173+
impl<T: ?Sized> PartialEq for NonNull<T> {
174+
#[inline]
175+
fn eq(&self, other: &Self) -> bool {
176+
self.as_ptr() == other.as_ptr()
177+
}
178+
}
179+
180+
#[stable(feature = "nonnull", since = "1.25.0")]
181+
impl<T: ?Sized> Ord for NonNull<T> {
182+
#[inline]
183+
fn cmp(&self, other: &Self) -> Ordering {
184+
self.as_ptr().cmp(&other.as_ptr())
185+
}
186+
}
187+
188+
#[stable(feature = "nonnull", since = "1.25.0")]
189+
impl<T: ?Sized> PartialOrd for NonNull<T> {
190+
#[inline]
191+
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
192+
self.as_ptr().partial_cmp(&other.as_ptr())
193+
}
194+
}
195+
196+
#[stable(feature = "nonnull", since = "1.25.0")]
197+
impl<T: ?Sized> hash::Hash for NonNull<T> {
198+
#[inline]
199+
fn hash<H: hash::Hasher>(&self, state: &mut H) {
200+
self.as_ptr().hash(state)
201+
}
202+
}
203+
204+
#[unstable(feature = "ptr_internals", issue = "0")]
205+
impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
206+
#[inline]
207+
fn from(unique: Unique<T>) -> Self {
208+
unsafe { NonNull::new_unchecked(unique.as_ptr()) }
209+
}
210+
}
211+
212+
#[stable(feature = "nonnull", since = "1.25.0")]
213+
impl<T: ?Sized> From<&mut T> for NonNull<T> {
214+
#[inline]
215+
fn from(reference: &mut T) -> Self {
216+
unsafe { NonNull { pointer: reference as *mut T } }
217+
}
218+
}
219+
220+
#[stable(feature = "nonnull", since = "1.25.0")]
221+
impl<T: ?Sized> From<&T> for NonNull<T> {
222+
#[inline]
223+
fn from(reference: &T) -> Self {
224+
unsafe { NonNull { pointer: reference as *const T } }
225+
}
226+
}

0 commit comments

Comments
 (0)