diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index a16970e9fd180..ac20897d258fb 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -662,6 +662,11 @@ impl<T: ?Sized> *const T {
     /// will only affect the pointer part, whereas for (thin) pointers to
     /// sized types, this has the same effect as a simple assignment.
     ///
+    /// The resulting pointer will have provenance of `val`, i.e., for a fat
+    /// pointer, this operation is semantically the same as creating a new
+    /// fat pointer with the data pointer value of `val` but the metadata of
+    /// `self`.
+    ///
     /// # Examples
     ///
     /// This function is primarily useful for allowing byte-wise pointer
@@ -673,13 +678,17 @@ impl<T: ?Sized> *const T {
     /// let arr: [i32; 3] = [1, 2, 3];
     /// let mut ptr = &arr[0] as *const dyn Debug;
     /// let thin = ptr as *const u8;
-    /// ptr = ptr.set_ptr_value(unsafe { thin.add(8).cast() });
-    /// assert_eq!(unsafe { *(ptr as *const i32) }, 3);
+    /// unsafe {
+    ///     ptr = ptr.set_ptr_value(thin.add(8));
+    ///     # assert_eq!(*(ptr as *const i32), 3);
+    ///     println!("{:?}", &*ptr); // will print "3"
+    /// }
     /// ```
     #[unstable(feature = "set_ptr_value", issue = "75091")]
+    #[must_use = "returns a new pointer rather than modifying its argument"]
     #[inline]
-    pub fn set_ptr_value(mut self, val: *const ()) -> Self {
-        let thin = &mut self as *mut *const T as *mut *const ();
+    pub fn set_ptr_value(mut self, val: *const u8) -> Self {
+        let thin = &mut self as *mut *const T as *mut *const u8;
         // SAFETY: In case of a thin pointer, this operations is identical
         // to a simple assignment. In case of a fat pointer, with the current
         // fat pointer layout implementation, the first field of such a
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index b47f90c599629..df00139118aa4 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -718,6 +718,11 @@ impl<T: ?Sized> *mut T {
     /// will only affect the pointer part, whereas for (thin) pointers to
     /// sized types, this has the same effect as a simple assignment.
     ///
+    /// The resulting pointer will have provenance of `val`, i.e., for a fat
+    /// pointer, this operation is semantically the same as creating a new
+    /// fat pointer with the data pointer value of `val` but the metadata of
+    /// `self`.
+    ///
     /// # Examples
     ///
     /// This function is primarily useful for allowing byte-wise pointer
@@ -729,13 +734,17 @@ impl<T: ?Sized> *mut T {
     /// let mut arr: [i32; 3] = [1, 2, 3];
     /// let mut ptr = &mut arr[0] as *mut dyn Debug;
     /// let thin = ptr as *mut u8;
-    /// ptr = ptr.set_ptr_value(unsafe { thin.add(8).cast() });
-    /// assert_eq!(unsafe { *(ptr as *mut i32) }, 3);
+    /// unsafe {
+    ///     ptr = ptr.set_ptr_value(thin.add(8));
+    ///     # assert_eq!(*(ptr as *mut i32), 3);
+    ///     println!("{:?}", &*ptr); // will print "3"
+    /// }
     /// ```
     #[unstable(feature = "set_ptr_value", issue = "75091")]
+    #[must_use = "returns a new pointer rather than modifying its argument"]
     #[inline]
-    pub fn set_ptr_value(mut self, val: *mut ()) -> Self {
-        let thin = &mut self as *mut *mut T as *mut *mut ();
+    pub fn set_ptr_value(mut self, val: *mut u8) -> Self {
+        let thin = &mut self as *mut *mut T as *mut *mut u8;
         // SAFETY: In case of a thin pointer, this operations is identical
         // to a simple assignment. In case of a fat pointer, with the current
         // fat pointer layout implementation, the first field of such a