about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-11-07 03:54:25 +0000
committerbors <bors@rust-lang.org>2019-11-07 03:54:25 +0000
commit7a76fe76f756895b8cda1e10398f2268656a2e0f (patch)
treea630f58f51bc8e94ffe1eb7eed1a2806d91843b6 /src/libcore
parentcaf018714189db0b15f9f803adfcb4572ab7a988 (diff)
parentb59d16600628fc9b9c82eb0140c74325a44e262a (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.rs9
-rw-r--r--src/libcore/lib.rs2
-rw-r--r--src/libcore/mem/maybe_uninit.rs1
-rw-r--r--src/libcore/ptr/mod.rs23
-rw-r--r--src/libcore/slice/mod.rs60
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)
 }