diff options
| author | bors <bors@rust-lang.org> | 2019-11-07 03:54:25 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-11-07 03:54:25 +0000 |
| commit | 7a76fe76f756895b8cda1e10398f2268656a2e0f (patch) | |
| tree | a630f58f51bc8e94ffe1eb7eed1a2806d91843b6 /src/libcore | |
| parent | caf018714189db0b15f9f803adfcb4572ab7a988 (diff) | |
| parent | b59d16600628fc9b9c82eb0140c74325a44e262a (diff) | |
Auto merge of #66175 - JohnTitor:rollup-ihqk5vn, r=JohnTitor
Rollup of 12 pull requests Successful merges: - #65794 (gate rustc_on_unimplemented under rustc_attrs) - #65945 (Optimize long-linker-command-line test) - #66044 (Improve uninit/zeroed lint) - #66076 (HIR docs: mention how to resolve method paths) - #66084 (Do not require extra LLVM backends for `x.py test` to pass) - #66111 (improve from_raw_parts docs) - #66114 (Improve std::thread::Result documentation) - #66117 (Fixed PhantomData markers in Arc and Rc) - #66146 (Remove unused parameters in `__thread_local_inner`) - #66147 (Miri: Refactor to_scalar_ptr out of existence) - #66162 (Fix broken link in README) - #66171 (Update link on CONTRIBUTING.md) Failed merges: r? @ghost
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/cell.rs | 9 | ||||
| -rw-r--r-- | src/libcore/lib.rs | 2 | ||||
| -rw-r--r-- | src/libcore/mem/maybe_uninit.rs | 1 | ||||
| -rw-r--r-- | src/libcore/ptr/mod.rs | 23 | ||||
| -rw-r--r-- | src/libcore/slice/mod.rs | 60 |
5 files changed, 69 insertions, 26 deletions
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index fda103a52d8..817c04d0af9 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -137,9 +137,11 @@ //! use std::cell::Cell; //! use std::ptr::NonNull; //! use std::intrinsics::abort; +//! use std::marker::PhantomData; //! //! struct Rc<T: ?Sized> { -//! ptr: NonNull<RcBox<T>> +//! ptr: NonNull<RcBox<T>>, +//! phantom: PhantomData<RcBox<T>>, //! } //! //! struct RcBox<T: ?Sized> { @@ -151,7 +153,10 @@ //! impl<T: ?Sized> Clone for Rc<T> { //! fn clone(&self) -> Rc<T> { //! self.inc_strong(); -//! Rc { ptr: self.ptr } +//! Rc { +//! ptr: self.ptr, +//! phantom: PhantomData, +//! } //! } //! } //! diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 1b67b05c730..ca431627147 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -89,7 +89,7 @@ #![feature(nll)] #![feature(exhaustive_patterns)] #![feature(no_core)] -#![feature(on_unimplemented)] +#![cfg_attr(bootstrap, feature(on_unimplemented))] #![feature(optin_builtin_traits)] #![feature(prelude_import)] #![feature(repr_simd, platform_intrinsics)] diff --git a/src/libcore/mem/maybe_uninit.rs b/src/libcore/mem/maybe_uninit.rs index 51ba260589f..03093139bc2 100644 --- a/src/libcore/mem/maybe_uninit.rs +++ b/src/libcore/mem/maybe_uninit.rs @@ -440,6 +440,7 @@ impl<T> MaybeUninit<T> { /// ``` #[stable(feature = "maybe_uninit", since = "1.36.0")] #[inline(always)] + #[cfg_attr(all(not(bootstrap)), rustc_diagnostic_item = "assume_init")] pub unsafe fn assume_init(self) -> T { intrinsics::panic_if_uninhabited::<T>(); ManuallyDrop::into_inner(self.value) diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs index 1355ce1aa43..1a13ac465f4 100644 --- a/src/libcore/ptr/mod.rs +++ b/src/libcore/ptr/mod.rs @@ -18,6 +18,10 @@ //! * A [null] pointer is *never* valid, not even for accesses of [size zero][zst]. //! * All pointers (except for the null pointer) are valid for all operations of //! [size zero][zst]. +//! * For a pointer to be valid, it is necessary, but not always sufficient, that the pointer +//! be *dereferencable*: the memory range of the given size starting at the pointer must all be +//! within the bounds of a single allocated object. Note that in Rust, +//! every (stack-allocated) variable is considered a separate allocated object. //! * All accesses performed by functions in this module are *non-atomic* in the sense //! of [atomic operations] used to synchronize between threads. This means it is //! undefined behavior to perform two concurrent accesses to the same location from different @@ -221,10 +225,15 @@ pub(crate) struct FatPtr<T> { pub(crate) len: usize, } -/// Forms a slice from a pointer and a length. +/// Forms a raw slice from a pointer and a length. /// /// The `len` argument is the number of **elements**, not the number of bytes. /// +/// This function is safe, but actually using the return value is unsafe. +/// See the documentation of [`from_raw_parts`] for slice safety requirements. +/// +/// [`from_raw_parts`]: ../../std/slice/fn.from_raw_parts.html +/// /// # Examples /// /// ```rust @@ -243,12 +252,16 @@ pub fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] { unsafe { Repr { raw: FatPtr { data, len } }.rust } } -/// Performs the same functionality as [`from_raw_parts`], except that a -/// mutable slice is returned. +/// Performs the same functionality as [`slice_from_raw_parts`], except that a +/// raw mutable slice is returned, as opposed to a raw immutable slice. /// -/// See the documentation of [`from_raw_parts`] for more details. +/// See the documentation of [`slice_from_raw_parts`] for more details. /// -/// [`from_raw_parts`]: ../../std/slice/fn.from_raw_parts.html +/// This function is safe, but actually using the return value is unsafe. +/// See the documentation of [`from_raw_parts_mut`] for slice safety requirements. +/// +/// [`slice_from_raw_parts`]: fn.slice_from_raw_parts.html +/// [`from_raw_parts_mut`]: ../../std/slice/fn.from_raw_parts_mut.html #[inline] #[unstable(feature = "slice_from_raw_parts", reason = "recently added", issue = "36925")] pub fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] { diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index cdada1252d2..7655b2f8065 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -5272,18 +5272,24 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> { /// /// # Safety /// -/// This function is unsafe as there is no guarantee that the given pointer is -/// valid for `len` elements, nor whether the lifetime inferred is a suitable -/// lifetime for the returned slice. +/// Behavior is undefined if any of the following conditions are violated: /// -/// `data` must be non-null and 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()`]. +/// * `data` must be [valid] for reads for `len * mem::size_of::<T>()` many bytes, +/// and it must be properly aligned. This means in particular: /// -/// The total size of the slice must be no larger than `isize::MAX` **bytes** -/// in memory. See the safety documentation of [`pointer::offset`]. +/// * The entire memory range of this slice must be contained within a single allocated object! +/// Slices can never span across multiple allocated objects. +/// * `data` must be non-null and 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 memory referenced by the returned slice must not be mutated for the duration +/// of lifetime `'a`, except inside an `UnsafeCell`. +/// +/// * The total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`. +/// See the safety documentation of [`pointer::offset`]. /// /// # Caveat /// @@ -5305,6 +5311,7 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> { /// assert_eq!(slice[0], 42); /// ``` /// +/// [valid]: ../../std/ptr/index.html#safety /// [`NonNull::dangling()`]: ../../std/ptr/struct.NonNull.html#method.dangling /// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset #[inline] @@ -5312,28 +5319,45 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> { pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] { debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice"); debug_assert!(mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize, - "attempt to create slice covering half the address space"); + "attempt to create slice covering at least half the address space"); &*ptr::slice_from_raw_parts(data, len) } /// Performs the same functionality as [`from_raw_parts`], except that a /// mutable slice is returned. /// -/// This function is unsafe for the same reasons as [`from_raw_parts`], as well -/// as not being able to provide a non-aliasing guarantee of the returned -/// mutable slice. `data` must be non-null and aligned even for zero-length -/// slices as with [`from_raw_parts`]. The total size of the slice must be no -/// larger than `isize::MAX` **bytes** in memory. +/// # Safety +/// +/// Behavior is undefined if any of the following conditions are violated: +/// +/// * `data` must be [valid] for writes for `len * mem::size_of::<T>()` many bytes, +/// and it must be properly aligned. This means in particular: /// -/// See the documentation of [`from_raw_parts`] for more details. +/// * The entire memory range of this slice must be contained within a single allocated object! +/// Slices can never span across multiple allocated objects. +/// * `data` must be non-null and 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 memory referenced by the returned slice must not be accessed through any other pointer +/// (not derived from the return value) for the duration of lifetime `'a`. +/// Both read and write accesses are forbidden. +/// +/// * The total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`. +/// See the safety documentation of [`pointer::offset`]. +/// +/// [valid]: ../../std/ptr/index.html#safety +/// [`NonNull::dangling()`]: ../../std/ptr/struct.NonNull.html#method.dangling +/// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset /// [`from_raw_parts`]: ../../std/slice/fn.from_raw_parts.html #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] { debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice"); debug_assert!(mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize, - "attempt to create slice covering half the address space"); + "attempt to create slice covering at least half the address space"); &mut *ptr::slice_from_raw_parts_mut(data, len) } |
