]> git.proxmox.com Git - rustc.git/blobdiff - library/core/src/intrinsics.rs
Merge tag 'debian/1.52.1+dfsg1-1_exp2' into proxmox/buster
[rustc.git] / library / core / src / intrinsics.rs
index 7c1a9b82f99b25aeb2739584089602d08195d633..073210c5b68573c4d06cca1569ba39c285b626c7 100644 (file)
@@ -65,9 +65,13 @@ use crate::sync::atomic::{self, AtomicBool, AtomicI32, AtomicIsize, AtomicU32, O
 #[stable(feature = "drop_in_place", since = "1.8.0")]
 #[rustc_deprecated(
     reason = "no longer an intrinsic - use `ptr::drop_in_place` directly",
-    since = "1.18.0"
+    since = "1.52.0"
 )]
-pub use crate::ptr::drop_in_place;
+#[inline]
+pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
+    // SAFETY: see `ptr::drop_in_place`
+    unsafe { crate::ptr::drop_in_place(to_drop) }
+}
 
 extern "rust-intrinsic" {
     // N.B., these intrinsics take raw pointers because they mutate aliased
@@ -833,6 +837,7 @@ extern "rust-intrinsic" {
     ///
     /// This exists solely for [`mem::forget_unsized`]; normal `forget` uses
     /// `ManuallyDrop` instead.
+    #[rustc_const_unstable(feature = "const_intrinsic_forget", issue = "none")]
     pub fn forget<T: ?Sized>(_: T);
 
     /// Reinterprets the bits of a value of one type as another type.
@@ -845,6 +850,12 @@ extern "rust-intrinsic" {
     /// destination value, then forgets the original. It's equivalent to C's
     /// `memcpy` under the hood, just like `transmute_copy`.
     ///
+    /// Because `transmute` is a by-value operation, alignment of the *transmuted values
+    /// themselves* is not a concern. As with any other function, the compiler already ensures
+    /// both `T` and `U` are properly aligned. However, when transmuting values that *point
+    /// elsewhere* (such as pointers, references, boxes…), the caller has to ensure proper
+    /// alignment of the pointed-to values.
+    ///
     /// `transmute` is **incredibly** unsafe. There are a vast number of ways to
     /// cause [undefined behavior][ub] with this function. `transmute` should be
     /// the absolute last resort.
@@ -964,7 +975,13 @@ extern "rust-intrinsic" {
     /// assert_eq!(b"Rust", &[82, 117, 115, 116]);
     /// ```
     ///
-    /// Turning a `Vec<&T>` into a `Vec<Option<&T>>`:
+    /// Turning a `Vec<&T>` into a `Vec<Option<&T>>`.
+    ///
+    /// To transmute the inner type of the contents of a container, you must make sure to not
+    /// violate any of the container's invariants. For `Vec`, this means that both the size
+    /// *and alignment* of the inner types have to match. Other containers might rely on the
+    /// size of the type, alignment, or even the `TypeId`, in which case transmuting wouldn't
+    /// be possible at all without violating the container invariants.
     ///
     /// ```
     /// let store = [0, 1, 2, 3];
@@ -990,14 +1007,11 @@ extern "rust-intrinsic" {
     ///
     /// let v_clone = v_orig.clone();
     ///
-    /// // The no-copy, unsafe way, still using transmute, but not relying on the data layout.
-    /// // Like the first approach, this reuses the `Vec` internals.
-    /// // Therefore, the new inner type must have the
-    /// // exact same size, *and the same alignment*, as the old type.
-    /// // The same caveats exist for this method as transmute, for
-    /// // the original inner type (`&i32`) to the converted inner type
-    /// // (`Option<&i32>`), so read the nomicon pages linked above and also
-    /// // consult the [`from_raw_parts`] documentation.
+    /// // This is the proper no-copy, unsafe way of "transmuting" a `Vec`, without relying on the
+    /// // data layout. Instead of literally calling `transmute`, we perform a pointer cast, but
+    /// // in terms of converting the original inner type (`&i32`) to the new one (`Option<&i32>`),
+    /// // this has all the same caveats. Besides the information provided above, also consult the
+    /// // [`from_raw_parts`] documentation.
     /// let v_from_raw = unsafe {
     // FIXME Update this when vec_into_raw_parts is stabilized
     ///     // Ensure the original vector is not dropped.
@@ -1092,8 +1106,7 @@ extern "rust-intrinsic" {
     /// bounds or arithmetic overflow occurs then any further use of the
     /// returned value will result in undefined behavior.
     ///
-    /// The stabilized version of this intrinsic is
-    /// [`std::pointer::offset`](../../std/primitive.pointer.html#method.offset).
+    /// The stabilized version of this intrinsic is [`pointer::offset`].
     #[must_use = "returns a new pointer rather than modifying its argument"]
     #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")]
     pub fn offset<T>(dst: *const T, offset: isize) -> *const T;
@@ -1110,8 +1123,7 @@ extern "rust-intrinsic" {
     /// object, and it wraps with two's complement arithmetic. The resulting
     /// value is not necessarily valid to be used to actually access memory.
     ///
-    /// The stabilized version of this intrinsic is
-    /// [`std::pointer::wrapping_offset`](../../std/primitive.pointer.html#method.wrapping_offset).
+    /// The stabilized version of this intrinsic is [`pointer::wrapping_offset`].
     #[must_use = "returns a new pointer rather than modifying its argument"]
     #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")]
     pub fn arith_offset<T>(dst: *const T, offset: isize) -> *const T;
@@ -1586,7 +1598,7 @@ extern "rust-intrinsic" {
     /// Safe wrappers for this intrinsic are available on the integer
     /// primitives via the `checked_div` method. For example,
     /// [`u32::checked_div`]
-    #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
+    #[rustc_const_stable(feature = "const_int_unchecked_arith", since = "1.52.0")]
     pub fn unchecked_div<T: Copy>(x: T, y: T) -> T;
     /// Returns the remainder of an unchecked division, resulting in
     /// undefined behavior when `y == 0` or `x == T::MIN && y == -1`
@@ -1594,7 +1606,7 @@ extern "rust-intrinsic" {
     /// Safe wrappers for this intrinsic are available on the integer
     /// primitives via the `checked_rem` method. For example,
     /// [`u32::checked_rem`]
-    #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
+    #[rustc_const_stable(feature = "const_int_unchecked_arith", since = "1.52.0")]
     pub fn unchecked_rem<T: Copy>(x: T, y: T) -> T;
 
     /// Performs an unchecked left shift, resulting in undefined behavior when
@@ -1688,8 +1700,8 @@ extern "rust-intrinsic" {
     #[rustc_const_stable(feature = "const_int_saturating", since = "1.40.0")]
     pub fn saturating_sub<T: Copy>(a: T, b: T) -> T;
 
-    /// Returns the value of the discriminant for the variant in 'v',
-    /// cast to a `u64`; if `T` has no discriminant, returns `0`.
+    /// Returns the value of the discriminant for the variant in 'v';
+    /// if `T` has no discriminant, returns `0`.
     ///
     /// The stabilized version of this intrinsic is [`core::mem::discriminant`](crate::mem::discriminant).
     #[rustc_const_unstable(feature = "const_discriminant", issue = "69821")]
@@ -1743,18 +1755,6 @@ pub(crate) fn is_aligned_and_not_null<T>(ptr: *const T) -> bool {
     !ptr.is_null() && ptr as usize % mem::align_of::<T>() == 0
 }
 
-/// Checks whether the regions of memory starting at `src` and `dst` of size
-/// `count * size_of::<T>()` do *not* overlap.
-pub(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) -> bool {
-    let src_usize = src as usize;
-    let dst_usize = dst as usize;
-    let size = mem::size_of::<T>().checked_mul(count).unwrap();
-    let diff = if src_usize > dst_usize { src_usize - dst_usize } else { dst_usize - src_usize };
-    // If the absolute distance between the ptrs is at least as big as the size of the buffer,
-    // they do not overlap.
-    diff >= size
-}
-
 /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
 /// and destination must *not* overlap.
 ///