about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-07-14 17:11:02 +0000
committerbors <bors@rust-lang.org>2020-07-14 17:11:02 +0000
commit2002ebacfbca288830a3c308ddc8189705c608fe (patch)
treed02268730c1ae866eb4a1ec31e144592b868be3d /src/libcore
parentc724b67e1b474262917a5154d74e7072267593fe (diff)
parent5414eae4521d0b6141b9db4c44be144757e5d5fb (diff)
downloadrust-2002ebacfbca288830a3c308ddc8189705c608fe.tar.gz
rust-2002ebacfbca288830a3c308ddc8189705c608fe.zip
Auto merge of #74330 - Manishearth:rollup-mrc09pb, r=Manishearth
Rollup of 15 pull requests

Successful merges:

 - #71237 (Add Ayu theme to rustdoc)
 - #73720 (Clean up E0704 error explanation)
 - #73866 (Obviate #[allow(improper_ctypes_definitions)])
 - #73965 (typeck: check for infer before type impls trait)
 - #73986 (add (unchecked) indexing methods to raw (and NonNull) slices)
 - #74173 (Detect tuple struct incorrectly used as struct pat)
 - #74220 (Refactor Windows `parse_prefix`)
 - #74227 (Remove an unwrap in layout computation)
 - #74239 (Update llvm-project to latest origin/rustc/10.0-2020-05-05 commit )
 - #74257 (don't mark linux kernel module targets as a unix environment)
 - #74270 (typeck: report placeholder type error w/out span)
 - #74296 (Clarify the description for rfind)
 - #74310 (Use `ArrayVec` in `SparseBitSet`.)
 - #74316 (Remove unnecessary type hints from Wake internals)
 - #74324 (Update Clippy)

Failed merges:

r? @ghost
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/lib.rs1
-rw-r--r--src/libcore/ptr/const_ptr.rs50
-rw-r--r--src/libcore/ptr/mut_ptr.rs51
-rw-r--r--src/libcore/ptr/non_null.rs53
-rw-r--r--src/libcore/slice/mod.rs111
-rw-r--r--src/libcore/str/mod.rs163
6 files changed, 293 insertions, 136 deletions
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 820c0a49e7f..c7496c209bc 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -148,6 +148,7 @@
 #![feature(associated_type_bounds)]
 #![feature(const_type_id)]
 #![feature(const_caller_location)]
+#![feature(slice_ptr_get)]
 #![feature(no_niche)] // rust-lang/rust#68303
 #![feature(unsafe_block_in_unsafe_fn)]
 #![deny(unsafe_op_in_unsafe_fn)]
diff --git a/src/libcore/ptr/const_ptr.rs b/src/libcore/ptr/const_ptr.rs
index d1d7a715238..39d4aca636a 100644
--- a/src/libcore/ptr/const_ptr.rs
+++ b/src/libcore/ptr/const_ptr.rs
@@ -2,6 +2,7 @@ use super::*;
 use crate::cmp::Ordering::{self, Equal, Greater, Less};
 use crate::intrinsics;
 use crate::mem;
+use crate::slice::SliceIndex;
 
 #[lang = "const_ptr"]
 impl<T: ?Sized> *const T {
@@ -826,6 +827,55 @@ impl<T> *const [T] {
         // Only `std` can make this guarantee.
         unsafe { Repr { rust: self }.raw }.len
     }
+
+    /// Returns a raw pointer to the slice's buffer.
+    ///
+    /// This is equivalent to casting `self` to `*const T`, but more type-safe.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// #![feature(slice_ptr_get)]
+    /// use std::ptr;
+    ///
+    /// let slice: *const [i8] = ptr::slice_from_raw_parts(ptr::null(), 3);
+    /// assert_eq!(slice.as_ptr(), 0 as *const i8);
+    /// ```
+    #[inline]
+    #[unstable(feature = "slice_ptr_get", issue = "74265")]
+    #[rustc_const_unstable(feature = "slice_ptr_get", issue = "74265")]
+    pub const fn as_ptr(self) -> *const T {
+        self as *const T
+    }
+
+    /// Returns a raw pointer to an element or subslice, without doing bounds
+    /// checking.
+    ///
+    /// Calling this method with an out-of-bounds index or when `self` is not dereferencable
+    /// is *[undefined behavior]* even if the resulting pointer is not used.
+    ///
+    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(slice_ptr_get)]
+    ///
+    /// let x = &[1, 2, 4] as *const [i32];
+    ///
+    /// unsafe {
+    ///     assert_eq!(x.get_unchecked(1), x.as_ptr().add(1));
+    /// }
+    /// ```
+    #[unstable(feature = "slice_ptr_get", issue = "74265")]
+    #[inline]
+    pub unsafe fn get_unchecked<I>(self, index: I) -> *const I::Output
+    where
+        I: SliceIndex<[T]>,
+    {
+        // SAFETY: the caller ensures that `self` is dereferencable and `index` in-bounds.
+        unsafe { index.get_unchecked(self) }
+    }
 }
 
 // Equality for pointers
diff --git a/src/libcore/ptr/mut_ptr.rs b/src/libcore/ptr/mut_ptr.rs
index 7d4b6339b51..644465d7d17 100644
--- a/src/libcore/ptr/mut_ptr.rs
+++ b/src/libcore/ptr/mut_ptr.rs
@@ -1,6 +1,7 @@
 use super::*;
 use crate::cmp::Ordering::{self, Equal, Greater, Less};
 use crate::intrinsics;
+use crate::slice::SliceIndex;
 
 #[lang = "mut_ptr"]
 impl<T: ?Sized> *mut T {
@@ -1014,7 +1015,6 @@ impl<T> *mut [T] {
     ///
     /// ```rust
     /// #![feature(slice_ptr_len)]
-    ///
     /// use std::ptr;
     ///
     /// let slice: *mut [i8] = ptr::slice_from_raw_parts_mut(ptr::null_mut(), 3);
@@ -1028,6 +1028,55 @@ impl<T> *mut [T] {
         // Only `std` can make this guarantee.
         unsafe { Repr { rust_mut: self }.raw }.len
     }
+
+    /// Returns a raw pointer to the slice's buffer.
+    ///
+    /// This is equivalent to casting `self` to `*mut T`, but more type-safe.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// #![feature(slice_ptr_get)]
+    /// use std::ptr;
+    ///
+    /// let slice: *mut [i8] = ptr::slice_from_raw_parts_mut(ptr::null_mut(), 3);
+    /// assert_eq!(slice.as_mut_ptr(), 0 as *mut i8);
+    /// ```
+    #[inline]
+    #[unstable(feature = "slice_ptr_get", issue = "74265")]
+    #[rustc_const_unstable(feature = "slice_ptr_get", issue = "74265")]
+    pub const fn as_mut_ptr(self) -> *mut T {
+        self as *mut T
+    }
+
+    /// Returns a raw pointer to an element or subslice, without doing bounds
+    /// checking.
+    ///
+    /// Calling this method with an out-of-bounds index or when `self` is not dereferencable
+    /// is *[undefined behavior]* even if the resulting pointer is not used.
+    ///
+    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(slice_ptr_get)]
+    ///
+    /// let x = &mut [1, 2, 4] as *mut [i32];
+    ///
+    /// unsafe {
+    ///     assert_eq!(x.get_unchecked_mut(1), x.as_mut_ptr().add(1));
+    /// }
+    /// ```
+    #[unstable(feature = "slice_ptr_get", issue = "74265")]
+    #[inline]
+    pub unsafe fn get_unchecked_mut<I>(self, index: I) -> *mut I::Output
+    where
+        I: SliceIndex<[T]>,
+    {
+        // SAFETY: the caller ensures that `self` is dereferencable and `index` in-bounds.
+        unsafe { index.get_unchecked_mut(self) }
+    }
 }
 
 // Equality for pointers
diff --git a/src/libcore/ptr/non_null.rs b/src/libcore/ptr/non_null.rs
index c2d31bfb6a4..b362a49d604 100644
--- a/src/libcore/ptr/non_null.rs
+++ b/src/libcore/ptr/non_null.rs
@@ -6,6 +6,7 @@ use crate::marker::Unsize;
 use crate::mem;
 use crate::ops::{CoerceUnsized, DispatchFromDyn};
 use crate::ptr::Unique;
+use crate::slice::SliceIndex;
 
 /// `*mut T` but non-zero and covariant.
 ///
@@ -192,7 +193,6 @@ impl<T> NonNull<[T]> {
     ///
     /// ```rust
     /// #![feature(slice_ptr_len, nonnull_slice_from_raw_parts)]
-    ///
     /// use std::ptr::NonNull;
     ///
     /// let slice: NonNull<[i8]> = NonNull::slice_from_raw_parts(NonNull::dangling(), 3);
@@ -204,6 +204,57 @@ impl<T> NonNull<[T]> {
     pub const fn len(self) -> usize {
         self.as_ptr().len()
     }
+
+    /// Returns a non-null pointer to the slice's buffer.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// #![feature(slice_ptr_get, nonnull_slice_from_raw_parts)]
+    /// use std::ptr::NonNull;
+    ///
+    /// let slice: NonNull<[i8]> = NonNull::slice_from_raw_parts(NonNull::dangling(), 3);
+    /// assert_eq!(slice.as_non_null_ptr(), NonNull::new(1 as *mut i8).unwrap());
+    /// ```
+    #[inline]
+    #[unstable(feature = "slice_ptr_get", issue = "74265")]
+    #[rustc_const_unstable(feature = "slice_ptr_get", issue = "74265")]
+    pub const fn as_non_null_ptr(self) -> NonNull<T> {
+        // SAFETY: We know `self` is non-null.
+        unsafe { NonNull::new_unchecked(self.as_ptr().as_mut_ptr()) }
+    }
+
+    /// Returns a raw pointer to an element or subslice, without doing bounds
+    /// checking.
+    ///
+    /// Calling this method with an out-of-bounds index or when `self` is not dereferencable
+    /// is *[undefined behavior]* even if the resulting pointer is not used.
+    ///
+    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(slice_ptr_get, nonnull_slice_from_raw_parts)]
+    /// use std::ptr::NonNull;
+    ///
+    /// let x = &mut [1, 2, 4];
+    /// let x = NonNull::slice_from_raw_parts(NonNull::new(x.as_mut_ptr()).unwrap(), x.len());
+    ///
+    /// unsafe {
+    ///     assert_eq!(x.get_unchecked_mut(1).as_ptr(), x.as_non_null_ptr().as_ptr().add(1));
+    /// }
+    /// ```
+    #[unstable(feature = "slice_ptr_get", issue = "74265")]
+    #[inline]
+    pub unsafe fn get_unchecked_mut<I>(self, index: I) -> NonNull<I::Output>
+    where
+        I: SliceIndex<[T]>,
+    {
+        // SAFETY: the caller ensures that `self` is dereferencable and `index` in-bounds.
+        // As a consequence, the resulting pointer cannot be NULL.
+        unsafe { NonNull::new_unchecked(self.as_ptr().get_unchecked_mut(index)) }
+    }
 }
 
 #[stable(feature = "nonnull", since = "1.25.0")]
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index bed8495993f..0e202bb7801 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -310,8 +310,10 @@ impl<T> [T] {
     where
         I: SliceIndex<Self>,
     {
-        // SAFETY: the caller must uphold the safety requirements for `get_unchecked`.
-        unsafe { index.get_unchecked(self) }
+        // SAFETY: the caller must uphold most of the safety requirements for `get_unchecked`;
+        // the slice is dereferencable because `self` is a safe reference.
+        // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is.
+        unsafe { &*index.get_unchecked(self) }
     }
 
     /// Returns a mutable reference to an element or subslice, without doing
@@ -342,8 +344,10 @@ impl<T> [T] {
     where
         I: SliceIndex<Self>,
     {
-        // SAFETY: the caller must uphold the safety requirements for `get_unchecked_mut`.
-        unsafe { index.get_unchecked_mut(self) }
+        // SAFETY: the caller must uphold the safety requirements for `get_unchecked_mut`;
+        // the slice is dereferencable because `self` is a safe reference.
+        // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is.
+        unsafe { &mut *index.get_unchecked_mut(self) }
     }
 
     /// Returns a raw pointer to the slice's buffer.
@@ -3010,6 +3014,9 @@ mod private_slice_index {
 }
 
 /// A helper trait used for indexing operations.
+///
+/// Implementations of this trait have to promise that if the argument
+/// to `get_(mut_)unchecked` is a safe reference, then so is the result.
 #[stable(feature = "slice_get_slice", since = "1.28.0")]
 #[rustc_on_unimplemented(
     on(T = "str", label = "string indices are ranges of `usize`",),
@@ -3021,7 +3028,7 @@ see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#ind
     message = "the type `{T}` cannot be indexed by `{Self}`",
     label = "slice indices are of type `usize` or ranges of `usize`"
 )]
-pub trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
+pub unsafe trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
     /// The output type returned by methods.
     #[stable(feature = "slice_get_slice", since = "1.28.0")]
     type Output: ?Sized;
@@ -3038,21 +3045,21 @@ pub trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
 
     /// Returns a shared reference to the output at this location, without
     /// performing any bounds checking.
-    /// Calling this method with an out-of-bounds index is *[undefined behavior]*
-    /// even if the resulting reference is not used.
+    /// Calling this method with an out-of-bounds index or a dangling `slice` pointer
+    /// is *[undefined behavior]* even if the resulting reference is not used.
     ///
     /// [undefined behavior]: ../../reference/behavior-considered-undefined.html
     #[unstable(feature = "slice_index_methods", issue = "none")]
-    unsafe fn get_unchecked(self, slice: &T) -> &Self::Output;
+    unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output;
 
     /// Returns a mutable reference to the output at this location, without
     /// performing any bounds checking.
-    /// Calling this method with an out-of-bounds index is *[undefined behavior]*
-    /// even if the resulting reference is not used.
+    /// Calling this method with an out-of-bounds index or a dangling `slice` pointer
+    /// is *[undefined behavior]* even if the resulting reference is not used.
     ///
     /// [undefined behavior]: ../../reference/behavior-considered-undefined.html
     #[unstable(feature = "slice_index_methods", issue = "none")]
-    unsafe fn get_unchecked_mut(self, slice: &mut T) -> &mut Self::Output;
+    unsafe fn get_unchecked_mut(self, slice: *mut T) -> *mut Self::Output;
 
     /// Returns a shared reference to the output at this location, panicking
     /// if out of bounds.
@@ -3068,33 +3075,32 @@ pub trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
 }
 
 #[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
-impl<T> SliceIndex<[T]> for usize {
+unsafe impl<T> SliceIndex<[T]> for usize {
     type Output = T;
 
     #[inline]
     fn get(self, slice: &[T]) -> Option<&T> {
-        if self < slice.len() { unsafe { Some(self.get_unchecked(slice)) } } else { None }
+        if self < slice.len() { unsafe { Some(&*self.get_unchecked(slice)) } } else { None }
     }
 
     #[inline]
     fn get_mut(self, slice: &mut [T]) -> Option<&mut T> {
-        if self < slice.len() { unsafe { Some(self.get_unchecked_mut(slice)) } } else { None }
+        if self < slice.len() { unsafe { Some(&mut *self.get_unchecked_mut(slice)) } } else { None }
     }
 
     #[inline]
-    unsafe fn get_unchecked(self, slice: &[T]) -> &T {
-        // SAFETY: `slice` cannot be longer than `isize::MAX` and
-        // the caller guarantees that `self` is in bounds of `slice`
-        // so `self` cannot overflow an `isize`, so the call to `add` is safe.
-        // The obtained pointer comes from a reference which is guaranteed
-        // to be valid.
-        unsafe { &*slice.as_ptr().add(self) }
+    unsafe fn get_unchecked(self, slice: *const [T]) -> *const T {
+        // SAFETY: the caller guarantees that `slice` is not dangling, so it
+        // cannot be longer than `isize::MAX`. They also guarantee that
+        // `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
+        // so the call to `add` is safe.
+        unsafe { slice.as_ptr().add(self) }
     }
 
     #[inline]
-    unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut T {
+    unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut T {
         // SAFETY: see comments for `get_unchecked` above.
-        unsafe { &mut *slice.as_mut_ptr().add(self) }
+        unsafe { slice.as_mut_ptr().add(self) }
     }
 
     #[inline]
@@ -3111,7 +3117,7 @@ impl<T> SliceIndex<[T]> for usize {
 }
 
 #[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
-impl<T> SliceIndex<[T]> for ops::Range<usize> {
+unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
     type Output = [T];
 
     #[inline]
@@ -3119,7 +3125,7 @@ impl<T> SliceIndex<[T]> for ops::Range<usize> {
         if self.start > self.end || self.end > slice.len() {
             None
         } else {
-            unsafe { Some(self.get_unchecked(slice)) }
+            unsafe { Some(&*self.get_unchecked(slice)) }
         }
     }
 
@@ -3128,24 +3134,25 @@ impl<T> SliceIndex<[T]> for ops::Range<usize> {
         if self.start > self.end || self.end > slice.len() {
             None
         } else {
-            unsafe { Some(self.get_unchecked_mut(slice)) }
+            unsafe { Some(&mut *self.get_unchecked_mut(slice)) }
         }
     }
 
     #[inline]
-    unsafe fn get_unchecked(self, slice: &[T]) -> &[T] {
-        // SAFETY: `slice` cannot be longer than `isize::MAX` and
-        // the caller guarantees that `self` is in bounds of `slice`
-        // so `self` cannot overflow an `isize`, so the call to `add` is safe.
-        // Also, since the caller guarantees that `self` is in bounds of `slice`,
-        // `from_raw_parts` will give a subslice of `slice` which is always safe.
-        unsafe { from_raw_parts(slice.as_ptr().add(self.start), self.end - self.start) }
+    unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
+        // SAFETY: the caller guarantees that `slice` is not dangling, so it
+        // cannot be longer than `isize::MAX`. They also guarantee that
+        // `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
+        // so the call to `add` is safe.
+        unsafe { ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), self.end - self.start) }
     }
 
     #[inline]
-    unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] {
+    unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
         // SAFETY: see comments for `get_unchecked` above.
-        unsafe { from_raw_parts_mut(slice.as_mut_ptr().add(self.start), self.end - self.start) }
+        unsafe {
+            ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), self.end - self.start)
+        }
     }
 
     #[inline]
@@ -3155,7 +3162,7 @@ impl<T> SliceIndex<[T]> for ops::Range<usize> {
         } else if self.end > slice.len() {
             slice_index_len_fail(self.end, slice.len());
         }
-        unsafe { self.get_unchecked(slice) }
+        unsafe { &*self.get_unchecked(slice) }
     }
 
     #[inline]
@@ -3165,12 +3172,12 @@ impl<T> SliceIndex<[T]> for ops::Range<usize> {
         } else if self.end > slice.len() {
             slice_index_len_fail(self.end, slice.len());
         }
-        unsafe { self.get_unchecked_mut(slice) }
+        unsafe { &mut *self.get_unchecked_mut(slice) }
     }
 }
 
 #[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
-impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
+unsafe impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
     type Output = [T];
 
     #[inline]
@@ -3184,13 +3191,13 @@ impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
     }
 
     #[inline]
-    unsafe fn get_unchecked(self, slice: &[T]) -> &[T] {
+    unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
         // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
         unsafe { (0..self.end).get_unchecked(slice) }
     }
 
     #[inline]
-    unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] {
+    unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
         // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
         unsafe { (0..self.end).get_unchecked_mut(slice) }
     }
@@ -3207,7 +3214,7 @@ impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
 }
 
 #[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
-impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
+unsafe impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
     type Output = [T];
 
     #[inline]
@@ -3221,13 +3228,13 @@ impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
     }
 
     #[inline]
-    unsafe fn get_unchecked(self, slice: &[T]) -> &[T] {
+    unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
         // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
         unsafe { (self.start..slice.len()).get_unchecked(slice) }
     }
 
     #[inline]
-    unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] {
+    unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
         // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
         unsafe { (self.start..slice.len()).get_unchecked_mut(slice) }
     }
@@ -3244,7 +3251,7 @@ impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
 }
 
 #[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
-impl<T> SliceIndex<[T]> for ops::RangeFull {
+unsafe impl<T> SliceIndex<[T]> for ops::RangeFull {
     type Output = [T];
 
     #[inline]
@@ -3258,12 +3265,12 @@ impl<T> SliceIndex<[T]> for ops::RangeFull {
     }
 
     #[inline]
-    unsafe fn get_unchecked(self, slice: &[T]) -> &[T] {
+    unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
         slice
     }
 
     #[inline]
-    unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] {
+    unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
         slice
     }
 
@@ -3279,7 +3286,7 @@ impl<T> SliceIndex<[T]> for ops::RangeFull {
 }
 
 #[stable(feature = "inclusive_range", since = "1.26.0")]
-impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
+unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
     type Output = [T];
 
     #[inline]
@@ -3297,13 +3304,13 @@ impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
     }
 
     #[inline]
-    unsafe fn get_unchecked(self, slice: &[T]) -> &[T] {
+    unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
         // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
         unsafe { (*self.start()..self.end() + 1).get_unchecked(slice) }
     }
 
     #[inline]
-    unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] {
+    unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
         // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
         unsafe { (*self.start()..self.end() + 1).get_unchecked_mut(slice) }
     }
@@ -3326,7 +3333,7 @@ impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
 }
 
 #[stable(feature = "inclusive_range", since = "1.26.0")]
-impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
+unsafe impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
     type Output = [T];
 
     #[inline]
@@ -3340,13 +3347,13 @@ impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
     }
 
     #[inline]
-    unsafe fn get_unchecked(self, slice: &[T]) -> &[T] {
+    unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
         // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
         unsafe { (0..=self.end).get_unchecked(slice) }
     }
 
     #[inline]
-    unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] {
+    unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
         // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
         unsafe { (0..=self.end).get_unchecked_mut(slice) }
     }
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 003ed7df36e..393911675c7 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -1731,7 +1731,8 @@ Section: Trait implementations
 mod traits {
     use crate::cmp::Ordering;
     use crate::ops;
-    use crate::slice::{self, SliceIndex};
+    use crate::ptr;
+    use crate::slice::SliceIndex;
 
     /// Implements ordering of strings.
     ///
@@ -1822,7 +1823,7 @@ mod traits {
     ///
     /// Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`.
     #[stable(feature = "str_checked_slicing", since = "1.20.0")]
-    impl SliceIndex<str> for ops::RangeFull {
+    unsafe impl SliceIndex<str> for ops::RangeFull {
         type Output = str;
         #[inline]
         fn get(self, slice: &str) -> Option<&Self::Output> {
@@ -1833,11 +1834,11 @@ mod traits {
             Some(slice)
         }
         #[inline]
-        unsafe fn get_unchecked(self, slice: &str) -> &Self::Output {
+        unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
             slice
         }
         #[inline]
-        unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
+        unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
             slice
         }
         #[inline]
@@ -1886,7 +1887,7 @@ mod traits {
     /// // &s[3 .. 100];
     /// ```
     #[stable(feature = "str_checked_slicing", since = "1.20.0")]
-    impl SliceIndex<str> for ops::Range<usize> {
+    unsafe impl SliceIndex<str> for ops::Range<usize> {
         type Output = str;
         #[inline]
         fn get(self, slice: &str) -> Option<&Self::Output> {
@@ -1894,8 +1895,10 @@ mod traits {
                 && slice.is_char_boundary(self.start)
                 && slice.is_char_boundary(self.end)
             {
-                // SAFETY: just checked that `start` and `end` are on a char boundary.
-                Some(unsafe { self.get_unchecked(slice) })
+                // SAFETY: just checked that `start` and `end` are on a char boundary,
+                // and we are passing in a safe reference, so the return value will also be one.
+                // We also checked char boundaries, so this is valid UTF-8.
+                Some(unsafe { &*self.get_unchecked(slice) })
             } else {
                 None
             }
@@ -1907,34 +1910,28 @@ mod traits {
                 && slice.is_char_boundary(self.end)
             {
                 // SAFETY: just checked that `start` and `end` are on a char boundary.
-                Some(unsafe { self.get_unchecked_mut(slice) })
+                // We know the pointer is unique because we got it from `slice`.
+                Some(unsafe { &mut *self.get_unchecked_mut(slice) })
             } else {
                 None
             }
         }
         #[inline]
-        unsafe fn get_unchecked(self, slice: &str) -> &Self::Output {
+        unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
+            let slice = slice as *const [u8];
             // SAFETY: the caller guarantees that `self` is in bounds of `slice`
             // which satisfies all the conditions for `add`.
             let ptr = unsafe { slice.as_ptr().add(self.start) };
             let len = self.end - self.start;
-            // SAFETY: as the caller guarantees that `self` is in bounds of `slice`,
-            // we can safely construct a subslice with `from_raw_parts` and use it
-            // since we return a shared thus immutable reference.
-            // The call to `from_utf8_unchecked` is safe since the data comes from
-            // a `str` which is guaranteed to be valid utf8, since the caller
-            // must guarantee that `self.start` and `self.end` are char boundaries.
-            unsafe { super::from_utf8_unchecked(slice::from_raw_parts(ptr, len)) }
+            ptr::slice_from_raw_parts(ptr, len) as *const str
         }
         #[inline]
-        unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
+        unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
+            let slice = slice as *mut [u8];
             // SAFETY: see comments for `get_unchecked`.
             let ptr = unsafe { slice.as_mut_ptr().add(self.start) };
             let len = self.end - self.start;
-            // SAFETY: mostly identical to the comments for `get_unchecked`, except that we
-            // can return a mutable reference since the caller passed a mutable reference
-            // and is thus guaranteed to have exclusive write access to `slice`.
-            unsafe { super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr, len)) }
+            ptr::slice_from_raw_parts_mut(ptr, len) as *mut str
         }
         #[inline]
         fn index(self, slice: &str) -> &Self::Output {
@@ -1949,8 +1946,9 @@ mod traits {
                 && slice.is_char_boundary(self.start)
                 && slice.is_char_boundary(self.end)
             {
-                // SAFETY: just checked that `start` and `end` are on a char boundary.
-                unsafe { self.get_unchecked_mut(slice) }
+                // SAFETY: just checked that `start` and `end` are on a char boundary,
+                // and we are passing in a safe reference, so the return value will also be one.
+                unsafe { &mut *self.get_unchecked_mut(slice) }
             } else {
                 super::slice_error_fail(slice, self.start, self.end)
             }
@@ -1973,13 +1971,14 @@ mod traits {
     /// Panics if `end` does not point to the starting byte offset of a
     /// character (as defined by `is_char_boundary`), or if `end > len`.
     #[stable(feature = "str_checked_slicing", since = "1.20.0")]
-    impl SliceIndex<str> for ops::RangeTo<usize> {
+    unsafe impl SliceIndex<str> for ops::RangeTo<usize> {
         type Output = str;
         #[inline]
         fn get(self, slice: &str) -> Option<&Self::Output> {
             if slice.is_char_boundary(self.end) {
-                // SAFETY: just checked that `end` is on a char boundary.
-                Some(unsafe { self.get_unchecked(slice) })
+                // SAFETY: just checked that `end` is on a char boundary,
+                // and we are passing in a safe reference, so the return value will also be one.
+                Some(unsafe { &*self.get_unchecked(slice) })
             } else {
                 None
             }
@@ -1987,30 +1986,24 @@ mod traits {
         #[inline]
         fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
             if slice.is_char_boundary(self.end) {
-                // SAFETY: just checked that `end` is on a char boundary.
-                Some(unsafe { self.get_unchecked_mut(slice) })
+                // SAFETY: just checked that `end` is on a char boundary,
+                // and we are passing in a safe reference, so the return value will also be one.
+                Some(unsafe { &mut *self.get_unchecked_mut(slice) })
             } else {
                 None
             }
         }
         #[inline]
-        unsafe fn get_unchecked(self, slice: &str) -> &Self::Output {
+        unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
+            let slice = slice as *const [u8];
             let ptr = slice.as_ptr();
-            // SAFETY: as the caller guarantees that `self` is in bounds of `slice`,
-            // we can safely construct a subslice with `from_raw_parts` and use it
-            // since we return a shared thus immutable reference.
-            // The call to `from_utf8_unchecked` is safe since the data comes from
-            // a `str` which is guaranteed to be valid utf8, since the caller
-            // must guarantee that `self.end` is a char boundary.
-            unsafe { super::from_utf8_unchecked(slice::from_raw_parts(ptr, self.end)) }
+            ptr::slice_from_raw_parts(ptr, self.end) as *const str
         }
         #[inline]
-        unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
+        unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
+            let slice = slice as *mut [u8];
             let ptr = slice.as_mut_ptr();
-            // SAFETY: mostly identical to `get_unchecked`, except that we can safely
-            // return a mutable reference since the caller passed a mutable reference
-            // and is thus guaranteed to have exclusive write access to `slice`.
-            unsafe { super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr, self.end)) }
+            ptr::slice_from_raw_parts_mut(ptr, self.end) as *mut str
         }
         #[inline]
         fn index(self, slice: &str) -> &Self::Output {
@@ -2020,8 +2013,9 @@ mod traits {
         #[inline]
         fn index_mut(self, slice: &mut str) -> &mut Self::Output {
             if slice.is_char_boundary(self.end) {
-                // SAFETY: just checked that `end` is on a char boundary.
-                unsafe { self.get_unchecked_mut(slice) }
+                // SAFETY: just checked that `end` is on a char boundary,
+                // and we are passing in a safe reference, so the return value will also be one.
+                unsafe { &mut *self.get_unchecked_mut(slice) }
             } else {
                 super::slice_error_fail(slice, 0, self.end)
             }
@@ -2045,13 +2039,14 @@ mod traits {
     /// Panics if `begin` does not point to the starting byte offset of
     /// a character (as defined by `is_char_boundary`), or if `begin >= len`.
     #[stable(feature = "str_checked_slicing", since = "1.20.0")]
-    impl SliceIndex<str> for ops::RangeFrom<usize> {
+    unsafe impl SliceIndex<str> for ops::RangeFrom<usize> {
         type Output = str;
         #[inline]
         fn get(self, slice: &str) -> Option<&Self::Output> {
             if slice.is_char_boundary(self.start) {
-                // SAFETY: just checked that `start` is on a char boundary.
-                Some(unsafe { self.get_unchecked(slice) })
+                // SAFETY: just checked that `start` is on a char boundary,
+                // and we are passing in a safe reference, so the return value will also be one.
+                Some(unsafe { &*self.get_unchecked(slice) })
             } else {
                 None
             }
@@ -2059,35 +2054,29 @@ mod traits {
         #[inline]
         fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
             if slice.is_char_boundary(self.start) {
-                // SAFETY: just checked that `start` is on a char boundary.
-                Some(unsafe { self.get_unchecked_mut(slice) })
+                // SAFETY: just checked that `start` is on a char boundary,
+                // and we are passing in a safe reference, so the return value will also be one.
+                Some(unsafe { &mut *self.get_unchecked_mut(slice) })
             } else {
                 None
             }
         }
         #[inline]
-        unsafe fn get_unchecked(self, slice: &str) -> &Self::Output {
+        unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
+            let slice = slice as *const [u8];
             // SAFETY: the caller guarantees that `self` is in bounds of `slice`
             // which satisfies all the conditions for `add`.
             let ptr = unsafe { slice.as_ptr().add(self.start) };
             let len = slice.len() - self.start;
-            // SAFETY: as the caller guarantees that `self` is in bounds of `slice`,
-            // we can safely construct a subslice with `from_raw_parts` and use it
-            // since we return a shared thus immutable reference.
-            // The call to `from_utf8_unchecked` is safe since the data comes from
-            // a `str` which is guaranteed to be valid utf8, since the caller
-            // must guarantee that `self.start` is a char boundary.
-            unsafe { super::from_utf8_unchecked(slice::from_raw_parts(ptr, len)) }
+            ptr::slice_from_raw_parts(ptr, len) as *const str
         }
         #[inline]
-        unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
+        unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
+            let slice = slice as *mut [u8];
             // SAFETY: identical to `get_unchecked`.
             let ptr = unsafe { slice.as_mut_ptr().add(self.start) };
             let len = slice.len() - self.start;
-            // SAFETY: mostly identical to `get_unchecked`, except that we can safely
-            // return a mutable reference since the caller passed a mutable reference
-            // and is thus guaranteed to have exclusive write access to `slice`.
-            unsafe { super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr, len)) }
+            ptr::slice_from_raw_parts_mut(ptr, len) as *mut str
         }
         #[inline]
         fn index(self, slice: &str) -> &Self::Output {
@@ -2097,8 +2086,9 @@ mod traits {
         #[inline]
         fn index_mut(self, slice: &mut str) -> &mut Self::Output {
             if slice.is_char_boundary(self.start) {
-                // SAFETY: just checked that `start` is on a char boundary.
-                unsafe { self.get_unchecked_mut(slice) }
+                // SAFETY: just checked that `start` is on a char boundary,
+                // and we are passing in a safe reference, so the return value will also be one.
+                unsafe { &mut *self.get_unchecked_mut(slice) }
             } else {
                 super::slice_error_fail(slice, self.start, slice.len())
             }
@@ -2122,7 +2112,7 @@ mod traits {
     /// to the ending byte offset of a character (`end + 1` is either a starting
     /// byte offset or equal to `len`), if `begin > end`, or if `end >= len`.
     #[stable(feature = "inclusive_range", since = "1.26.0")]
-    impl SliceIndex<str> for ops::RangeInclusive<usize> {
+    unsafe impl SliceIndex<str> for ops::RangeInclusive<usize> {
         type Output = str;
         #[inline]
         fn get(self, slice: &str) -> Option<&Self::Output> {
@@ -2141,12 +2131,12 @@ mod traits {
             }
         }
         #[inline]
-        unsafe fn get_unchecked(self, slice: &str) -> &Self::Output {
+        unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
             // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
             unsafe { (*self.start()..self.end() + 1).get_unchecked(slice) }
         }
         #[inline]
-        unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
+        unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
             // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
             unsafe { (*self.start()..self.end() + 1).get_unchecked_mut(slice) }
         }
@@ -2181,7 +2171,7 @@ mod traits {
     /// (`end + 1` is either a starting byte offset as defined by
     /// `is_char_boundary`, or equal to `len`), or if `end >= len`.
     #[stable(feature = "inclusive_range", since = "1.26.0")]
-    impl SliceIndex<str> for ops::RangeToInclusive<usize> {
+    unsafe impl SliceIndex<str> for ops::RangeToInclusive<usize> {
         type Output = str;
         #[inline]
         fn get(self, slice: &str) -> Option<&Self::Output> {
@@ -2192,12 +2182,12 @@ mod traits {
             if self.end == usize::MAX { None } else { (..self.end + 1).get_mut(slice) }
         }
         #[inline]
-        unsafe fn get_unchecked(self, slice: &str) -> &Self::Output {
+        unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
             // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
             unsafe { (..self.end + 1).get_unchecked(slice) }
         }
         #[inline]
-        unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
+        unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
             // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
             unsafe { (..self.end + 1).get_unchecked_mut(slice) }
         }
@@ -2560,8 +2550,10 @@ impl str {
     #[stable(feature = "str_checked_slicing", since = "1.20.0")]
     #[inline]
     pub unsafe fn get_unchecked<I: SliceIndex<str>>(&self, i: I) -> &I::Output {
-        // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
-        unsafe { i.get_unchecked(self) }
+        // SAFETY: the caller must uphold the safety contract for `get_unchecked`;
+        // the slice is dereferencable because `self` is a safe reference.
+        // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is.
+        unsafe { &*i.get_unchecked(self) }
     }
 
     /// Returns a mutable, unchecked subslice of `str`.
@@ -2593,8 +2585,10 @@ impl str {
     #[stable(feature = "str_checked_slicing", since = "1.20.0")]
     #[inline]
     pub unsafe fn get_unchecked_mut<I: SliceIndex<str>>(&mut self, i: I) -> &mut I::Output {
-        // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
-        unsafe { i.get_unchecked_mut(self) }
+        // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`;
+        // the slice is dereferencable because `self` is a safe reference.
+        // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is.
+        unsafe { &mut *i.get_unchecked_mut(self) }
     }
 
     /// Creates a string slice from another string slice, bypassing safety
@@ -2644,8 +2638,10 @@ impl str {
     #[rustc_deprecated(since = "1.29.0", reason = "use `get_unchecked(begin..end)` instead")]
     #[inline]
     pub unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
-        // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
-        unsafe { (begin..end).get_unchecked(self) }
+        // SAFETY: the caller must uphold the safety contract for `get_unchecked`;
+        // the slice is dereferencable because `self` is a safe reference.
+        // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is.
+        unsafe { &*(begin..end).get_unchecked(self) }
     }
 
     /// Creates a string slice from another string slice, bypassing safety
@@ -2676,8 +2672,10 @@ impl str {
     #[rustc_deprecated(since = "1.29.0", reason = "use `get_unchecked_mut(begin..end)` instead")]
     #[inline]
     pub unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str {
-        // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
-        unsafe { (begin..end).get_unchecked_mut(self) }
+        // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`;
+        // the slice is dereferencable because `self` is a safe reference.
+        // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is.
+        unsafe { &mut *(begin..end).get_unchecked_mut(self) }
     }
 
     /// Divide one string slice into two at an index.
@@ -3158,11 +3156,11 @@ impl str {
     /// Simple patterns:
     ///
     /// ```
-    /// let s = "Löwe 老虎 Léopard";
+    /// let s = "Löwe 老虎 Léopard Gepardi";
     ///
     /// assert_eq!(s.find('L'), Some(0));
     /// assert_eq!(s.find('é'), Some(14));
-    /// assert_eq!(s.find("Léopard"), Some(13));
+    /// assert_eq!(s.find("pard"), Some(17));
     /// ```
     ///
     /// More complex patterns using point-free style and closures:
@@ -3190,8 +3188,8 @@ impl str {
         pat.into_searcher(self).next_match().map(|(i, _)| i)
     }
 
-    /// Returns the byte index of the last character of this string slice that
-    /// matches the pattern.
+    /// Returns the byte index for the first character of the rightmost match of the pattern in
+    /// this string slice.
     ///
     /// Returns [`None`] if the pattern doesn't match.
     ///
@@ -3207,10 +3205,11 @@ impl str {
     /// Simple patterns:
     ///
     /// ```
-    /// let s = "Löwe 老虎 Léopard";
+    /// let s = "Löwe 老虎 Léopard Gepardi";
     ///
     /// assert_eq!(s.rfind('L'), Some(13));
     /// assert_eq!(s.rfind('é'), Some(14));
+    /// assert_eq!(s.rfind("pard"), Some(24));
     /// ```
     ///
     /// More complex patterns with closures: