Skip to content

Rollup of 8 pull requests #75653

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Aug 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
0e010a6
Move to intra doc links for ascii.rs and panic.rs, updating the docs …
poliorcetics Aug 12, 2020
ac73474
Add explanation for `&mut self` method call when expecting `-> Self`
estebank Aug 17, 2020
be1fc40
Allowing raw ptr dereference in const fn
Aug 16, 2020
bdbb995
Mark x86_64-linux-kernel as *
scrabsha Aug 17, 2020
edb39c0
attempt to improve span_label docs
RalfJung Aug 11, 2020
93e074b
Add `as_uninit`-like methods to pointer types and unify documentation…
TimDiekmann Aug 17, 2020
cbc13c5
Clean up E0754 explanation
GuillaumeGomez Aug 17, 2020
509cad7
Switch to intra-doc links for std/src/error.rs
BoxyUwU Aug 17, 2020
b6d2868
Switch to intra-doc links for std/src/env.rs
BoxyUwU Aug 17, 2020
a2dfc3e
Switch to intra-doc links for std/src/alloc.rs
BoxyUwU Aug 17, 2020
e7a7279
Remove unnecessary links in env.rs
BoxyUwU Aug 17, 2020
4fa69cb
Improve display
GuillaumeGomez Aug 17, 2020
381a841
Rollup merge of #75389 - RalfJung:span_label, r=davidtwco
JohnTitor Aug 18, 2020
5498367
Rollup merge of #75392 - TimDiekmann:non-null-uninit-slice, r=RalfJung
JohnTitor Aug 18, 2020
d18719b
Rollup merge of #75464 - poliorcetics:intra-links-panic-and-ascii, r=…
JohnTitor Aug 18, 2020
8eb805c
Rollup merge of #75578 - 5M1Sec:master, r=oli-obk
JohnTitor Aug 18, 2020
48da675
Rollup merge of #75613 - estebank:explain-mut-method, r=petrochenkov
JohnTitor Aug 18, 2020
791768e
Rollup merge of #75626 - GuillaumeGomez:cleanup-e0754, r=pickfire
JohnTitor Aug 18, 2020
732bebd
Rollup merge of #75629 - EllenNyan:ellen-intra-doc-links, r=jyn514
JohnTitor Aug 18, 2020
51154d8
Rollup merge of #75634 - scileo:fix-75581, r=ehuss
JohnTitor Aug 18, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@
#![feature(optin_builtin_traits)]
#![feature(or_patterns)]
#![feature(prelude_import)]
#![feature(ptr_as_uninit)]
#![feature(repr_simd, platform_intrinsics)]
#![feature(rustc_attrs)]
#![feature(simd_ffi)]
Expand Down
134 changes: 117 additions & 17 deletions library/core/src/ptr/const_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use super::*;
use crate::cmp::Ordering::{self, Equal, Greater, Less};
use crate::intrinsics;
use crate::mem;
use crate::slice::SliceIndex;
use crate::slice::{self, SliceIndex};

#[lang = "const_ptr"]
impl<T: ?Sized> *const T {
Expand Down Expand Up @@ -48,32 +48,33 @@ impl<T: ?Sized> *const T {
self as _
}

/// Returns `None` if the pointer is null, or else returns a reference to
/// the value wrapped in `Some`.
/// Returns `None` if the pointer is null, or else returns a shared reference to
/// the value wrapped in `Some`. If the value may be uninitialized, [`as_uninit_ref`]
/// must be used instead.
///
/// # Safety
/// [`as_uninit_ref`]: #method.as_uninit_ref
///
/// While this method and its mutable counterpart are useful for
/// null-safety, it is important to note that this is still an unsafe
/// operation because the returned value could be pointing to invalid
/// memory.
/// # Safety
///
/// When calling this method, you have to ensure that *either* the pointer is NULL *or*
/// all of the following is true:
/// - it is properly aligned
/// - it must point to an initialized instance of T; in particular, the pointer must be
/// "dereferenceable" in the sense defined [here].
///
/// * The pointer must be properly aligned.
///
/// * It must be "dereferencable" in the sense defined in [the module documentation].
///
/// * The pointer must point to an initialized instance of `T`.
///
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
/// In particular, for the duration of this lifetime, the memory the pointer points to must
/// not get mutated (except inside `UnsafeCell`).
///
/// This applies even if the result of this method is unused!
/// (The part about being initialized is not yet fully decided, but until
/// it is, the only safe approach is to ensure that they are indeed initialized.)
///
/// Additionally, the lifetime `'a` returned is arbitrarily chosen and does
/// not necessarily reflect the actual lifetime of the data. *You* must enforce
/// Rust's aliasing rules. In particular, for the duration of this lifetime,
/// the memory the pointer points to must not get mutated (except inside `UnsafeCell`).
///
/// [here]: crate::ptr#safety
/// [the module documentation]: crate::ptr#safety
///
/// # Examples
///
Expand Down Expand Up @@ -111,6 +112,56 @@ impl<T: ?Sized> *const T {
if self.is_null() { None } else { unsafe { Some(&*self) } }
}

/// Returns `None` if the pointer is null, or else returns a shared reference to
/// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require
/// that the value has to be initialized.
///
/// [`as_ref`]: #method.as_ref
///
/// # Safety
///
/// When calling this method, you have to ensure that *either* the pointer is NULL *or*
/// all of the following is true:
///
/// * The pointer must be properly aligned.
///
/// * It must be "dereferencable" in the sense defined in [the module documentation].
///
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
/// In particular, for the duration of this lifetime, the memory the pointer points to must
/// not get mutated (except inside `UnsafeCell`).
///
/// This applies even if the result of this method is unused!
///
/// [the module documentation]: crate::ptr#safety
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(ptr_as_uninit)]
///
/// let ptr: *const u8 = &10u8 as *const u8;
///
/// unsafe {
/// if let Some(val_back) = ptr.as_uninit_ref() {
/// println!("We got back the value: {}!", val_back.assume_init());
/// }
/// }
/// ```
#[inline]
#[unstable(feature = "ptr_as_uninit", issue = "75402")]
pub unsafe fn as_uninit_ref<'a>(self) -> Option<&'a MaybeUninit<T>>
where
T: Sized,
{
// SAFETY: the caller must guarantee that `self` meets all the
// requirements for a reference.
if self.is_null() { None } else { Some(unsafe { &*(self as *const MaybeUninit<T>) }) }
}

/// Calculates the offset from a pointer.
///
/// `count` is in units of T; e.g., a `count` of 3 represents a pointer
Expand Down Expand Up @@ -925,6 +976,55 @@ impl<T> *const [T] {
// SAFETY: the caller ensures that `self` is dereferencable and `index` in-bounds.
unsafe { index.get_unchecked(self) }
}

/// Returns `None` if the pointer is null, or else returns a shared slice to
/// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require
/// that the value has to be initialized.
///
/// [`as_ref`]: #method.as_ref
///
/// # Safety
///
/// When calling this method, you have to ensure that *either* the pointer is NULL *or*
/// all of the following is true:
///
/// * The pointer must be [valid] for reads for `ptr.len() * mem::size_of::<T>()` many bytes,
/// and it must be properly aligned. This means in particular:
///
/// * The entire memory range of this slice must be contained within a single allocated object!
/// Slices can never span across multiple allocated objects.
///
/// * The pointer must be aligned even for zero-length slices. One
/// reason for this is that enum layout optimizations may rely on references
/// (including slices of any length) being aligned and non-null to distinguish
/// them from other data. You can obtain a pointer that is usable as `data`
/// for zero-length slices using [`NonNull::dangling()`].
///
/// * The total size `ptr.len() * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
/// See the safety documentation of [`pointer::offset`].
///
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
/// In particular, for the duration of this lifetime, the memory the pointer points to must
/// not get mutated (except inside `UnsafeCell`).
///
/// This applies even if the result of this method is unused!
///
/// See also [`slice::from_raw_parts`][].
///
/// [valid]: crate::ptr#safety
/// [`NonNull::dangling()`]: NonNull::dangling
/// [`pointer::offset`]: ../std/primitive.pointer.html#method.offset
#[inline]
#[unstable(feature = "ptr_as_uninit", issue = "75402")]
pub unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit<T>]> {
if self.is_null() {
None
} else {
// SAFETY: the caller must uphold the safety contract for `as_uninit_slice`.
Some(unsafe { slice::from_raw_parts(self as *const MaybeUninit<T>, self.len()) })
}
}
}

// Equality for pointers
Expand Down
Loading