mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-11 08:05:12 +00:00
safety-ptr: Add SAFETY on some unsafe blocks from libcore/ptr
Add documentation example to slice_from_raw_parts_mut() Add SAFETY explanations to some unsafe blocks in libcore/ptr * libcore/ptr/mod.rs * libcore/ptr/unique.rs * libcore/ptr/non_null.rs safety-mod.rs: Add SAFETY to slice_from_raw_parts(), slice_from_raw_parts_mut() slice_from_raw_parts_mut: Add documentation example safety-ptr-unique.rs: Add SAFETY to new() and cast() safety-ptr-non_null.rs: Add SAFETY to new() safety-ptr-non_null.rs: Add SAFETY to cast() safety-ptr-non_null.rs: Add SAFETY to from() impls safety-ptr-unique.rs: Add SAFETY to from() impls safety-ptr-non_null.rs: Add SAFETY to new() safety-ptr-unique.rs: Add SAFETY to new() safety-ptr-mod.rs: Fix safety explanation https://github.com/rust-lang/rust/pull/71507#discussion_r414488884 safety-prt-non_null.rs: Fix SAFETY comment syntax safety-ptr-unique.rs: Fix syntax for empty() safety-ptr-non_null.rs: Fix misuse of non-null for align_of() safety-ptr-non_null.rs: Remove incorrect SAFETY comment safety-ptr-unique.rs: Remove unsound SAFETY comment safety-ptr-mod.rs: Add std comment on slice_from_raw_parts guarantee safety-ptr-unique.rs: Remove incorrect safety comment Creating a Unique from a NonNull has strict guarantees that the current implementation does not guarantee https://github.com/rust-lang/rust/pull/71507#discussion_r415035952 safety-ptr: Re-adding ignore-tidy directive
This commit is contained in:
parent
b4a11d4dd9
commit
8558ccd5c4
@ -254,6 +254,9 @@ pub(crate) struct FatPtr<T> {
|
|||||||
#[stable(feature = "slice_from_raw_parts", since = "1.42.0")]
|
#[stable(feature = "slice_from_raw_parts", since = "1.42.0")]
|
||||||
#[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "67456")]
|
#[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "67456")]
|
||||||
pub const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
|
pub const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
|
||||||
|
// SAFETY: Accessing the value from the `Repr` union is safe since *const [T]
|
||||||
|
// and FatPtr have the same memory layouts. Only std can make this
|
||||||
|
// guarantee.
|
||||||
unsafe { Repr { raw: FatPtr { data, len } }.rust }
|
unsafe { Repr { raw: FatPtr { data, len } }.rust }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,10 +270,28 @@ pub const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
|
|||||||
///
|
///
|
||||||
/// [`slice_from_raw_parts`]: fn.slice_from_raw_parts.html
|
/// [`slice_from_raw_parts`]: fn.slice_from_raw_parts.html
|
||||||
/// [`from_raw_parts_mut`]: ../../std/slice/fn.from_raw_parts_mut.html
|
/// [`from_raw_parts_mut`]: ../../std/slice/fn.from_raw_parts_mut.html
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use std::ptr;
|
||||||
|
///
|
||||||
|
/// let x = &mut [5, 6, 7];
|
||||||
|
/// let raw_pointer = x.as_mut_ptr();
|
||||||
|
/// let slice = ptr::slice_from_raw_parts_mut(raw_pointer, 3);
|
||||||
|
///
|
||||||
|
/// unsafe {
|
||||||
|
/// (*slice)[2] = 99; // assign a value at an index in the slice
|
||||||
|
/// };
|
||||||
|
///
|
||||||
|
/// assert_eq!(unsafe { &*slice }[2], 99);
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "slice_from_raw_parts", since = "1.42.0")]
|
#[stable(feature = "slice_from_raw_parts", since = "1.42.0")]
|
||||||
#[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "67456")]
|
#[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "67456")]
|
||||||
pub const fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] {
|
pub const fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] {
|
||||||
|
// SAFETY: Accessing the value from the `Repr` union is safe since *mut [T]
|
||||||
|
// and FatPtr have the same memory layouts
|
||||||
unsafe { Repr { raw: FatPtr { data, len } }.rust_mut }
|
unsafe { Repr { raw: FatPtr { data, len } }.rust_mut }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,8 +7,6 @@ use crate::mem;
|
|||||||
use crate::ops::{CoerceUnsized, DispatchFromDyn};
|
use crate::ops::{CoerceUnsized, DispatchFromDyn};
|
||||||
use crate::ptr::Unique;
|
use crate::ptr::Unique;
|
||||||
|
|
||||||
// ignore-tidy-undocumented-unsafe
|
|
||||||
|
|
||||||
/// `*mut T` but non-zero and covariant.
|
/// `*mut T` but non-zero and covariant.
|
||||||
///
|
///
|
||||||
/// This is often the correct thing to use when building data structures using
|
/// This is often the correct thing to use when building data structures using
|
||||||
@ -69,6 +67,9 @@ impl<T: Sized> NonNull<T> {
|
|||||||
#[rustc_const_stable(feature = "const_nonnull_dangling", since = "1.32.0")]
|
#[rustc_const_stable(feature = "const_nonnull_dangling", since = "1.32.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn dangling() -> Self {
|
pub const fn dangling() -> Self {
|
||||||
|
// SAFETY: mem::align_of() returns a non-zero usize which is then casted
|
||||||
|
// to a *mut T. Therefore, `ptr` is not null and the conditions for
|
||||||
|
// calling new_unchecked() are respected.
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = mem::align_of::<T>() as *mut T;
|
let ptr = mem::align_of::<T>() as *mut T;
|
||||||
NonNull::new_unchecked(ptr)
|
NonNull::new_unchecked(ptr)
|
||||||
@ -93,7 +94,12 @@ impl<T: ?Sized> NonNull<T> {
|
|||||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(ptr: *mut T) -> Option<Self> {
|
pub fn new(ptr: *mut T) -> Option<Self> {
|
||||||
if !ptr.is_null() { Some(unsafe { Self::new_unchecked(ptr) }) } else { None }
|
if !ptr.is_null() {
|
||||||
|
// SAFETY: The pointer is already checked and is not null
|
||||||
|
Some(unsafe { Self::new_unchecked(ptr) })
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Acquires the underlying `*mut` pointer.
|
/// Acquires the underlying `*mut` pointer.
|
||||||
@ -131,6 +137,7 @@ impl<T: ?Sized> NonNull<T> {
|
|||||||
#[rustc_const_stable(feature = "const_nonnull_cast", since = "1.32.0")]
|
#[rustc_const_stable(feature = "const_nonnull_cast", since = "1.32.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn cast<U>(self) -> NonNull<U> {
|
pub const fn cast<U>(self) -> NonNull<U> {
|
||||||
|
// SAFETY: `self` is a `NonNull` pointer which is necessarily non-null
|
||||||
unsafe { NonNull::new_unchecked(self.as_ptr() as *mut U) }
|
unsafe { NonNull::new_unchecked(self.as_ptr() as *mut U) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -205,6 +212,8 @@ impl<T: ?Sized> hash::Hash for NonNull<T> {
|
|||||||
impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
|
impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(unique: Unique<T>) -> Self {
|
fn from(unique: Unique<T>) -> Self {
|
||||||
|
// SAFETY: A Unique pointer cannot be null, so the conditions for
|
||||||
|
// new_unchecked() are respected.
|
||||||
unsafe { NonNull::new_unchecked(unique.as_ptr()) }
|
unsafe { NonNull::new_unchecked(unique.as_ptr()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,6 +222,7 @@ impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
|
|||||||
impl<T: ?Sized> From<&mut T> for NonNull<T> {
|
impl<T: ?Sized> From<&mut T> for NonNull<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(reference: &mut T) -> Self {
|
fn from(reference: &mut T) -> Self {
|
||||||
|
// SAFETY: A mutable reference cannot be null.
|
||||||
unsafe { NonNull { pointer: reference as *mut T } }
|
unsafe { NonNull { pointer: reference as *mut T } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -221,6 +231,8 @@ impl<T: ?Sized> From<&mut T> for NonNull<T> {
|
|||||||
impl<T: ?Sized> From<&T> for NonNull<T> {
|
impl<T: ?Sized> From<&T> for NonNull<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(reference: &T) -> Self {
|
fn from(reference: &T) -> Self {
|
||||||
|
// SAFETY: A reference cannot be null, so the conditions for
|
||||||
|
// new_unchecked() are respected.
|
||||||
unsafe { NonNull { pointer: reference as *const T } }
|
unsafe { NonNull { pointer: reference as *const T } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,6 +74,8 @@ impl<T: Sized> Unique<T> {
|
|||||||
// FIXME: rename to dangling() to match NonNull?
|
// FIXME: rename to dangling() to match NonNull?
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn empty() -> Self {
|
pub const fn empty() -> Self {
|
||||||
|
// SAFETY: mem::align_of() returns a valid, non-null pointer. The
|
||||||
|
// conditions to call new_unchecked() are thus respected.
|
||||||
unsafe { Unique::new_unchecked(mem::align_of::<T>() as *mut T) }
|
unsafe { Unique::new_unchecked(mem::align_of::<T>() as *mut T) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,6 +96,7 @@ impl<T: ?Sized> Unique<T> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(ptr: *mut T) -> Option<Self> {
|
pub fn new(ptr: *mut T) -> Option<Self> {
|
||||||
if !ptr.is_null() {
|
if !ptr.is_null() {
|
||||||
|
// SAFETY: The pointer has already been checked and is not null.
|
||||||
Some(unsafe { Unique { pointer: ptr as _, _marker: PhantomData } })
|
Some(unsafe { Unique { pointer: ptr as _, _marker: PhantomData } })
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -129,6 +132,9 @@ impl<T: ?Sized> Unique<T> {
|
|||||||
/// Casts to a pointer of another type.
|
/// Casts to a pointer of another type.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn cast<U>(self) -> Unique<U> {
|
pub const fn cast<U>(self) -> Unique<U> {
|
||||||
|
// SAFETY: Unique::new_unchecked() creates a new unique and needs
|
||||||
|
// the given pointer to not be null.
|
||||||
|
// Since we are passing self as a pointer, it cannot be null.
|
||||||
unsafe { Unique::new_unchecked(self.as_ptr() as *mut U) }
|
unsafe { Unique::new_unchecked(self.as_ptr() as *mut U) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -168,6 +174,7 @@ impl<T: ?Sized> fmt::Pointer for Unique<T> {
|
|||||||
impl<T: ?Sized> From<&mut T> for Unique<T> {
|
impl<T: ?Sized> From<&mut T> for Unique<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(reference: &mut T) -> Self {
|
fn from(reference: &mut T) -> Self {
|
||||||
|
// SAFETY: A mutable reference cannot be null
|
||||||
unsafe { Unique { pointer: reference as *mut T, _marker: PhantomData } }
|
unsafe { Unique { pointer: reference as *mut T, _marker: PhantomData } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user