about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-03-11 09:37:19 +0000
committerbors <bors@rust-lang.org>2020-03-11 09:37:19 +0000
commit303d8aff6092709edd4dbd35b1c88e9aa40bf6d8 (patch)
treed1c781bd7041e9f7d374d93281f64d6803cbd9cd /src/libcore
parent15812785344d913d779d9738fe3cca8de56f71d5 (diff)
parent6a8683fcd0f51eb3e17c464f9c68967c71a62de5 (diff)
downloadrust-303d8aff6092709edd4dbd35b1c88e9aa40bf6d8.tar.gz
rust-303d8aff6092709edd4dbd35b1c88e9aa40bf6d8.zip
Auto merge of #69914 - Centril:rollup-wtmdinz, r=Centril
Rollup of 10 pull requests

Successful merges:

 - #66059 (mem::zeroed/uninit: panic on types that do not permit zero-initialization)
 - #69373 (Stabilize const for integer {to,from}_{be,le,ne}_bytes methods)
 - #69591 (Use TypeRelating for instantiating query responses)
 - #69625 (Implement nth, last, and count for iter::Copied)
 - #69645 (const forget tests)
 - #69766 (Make Point `Copy` in arithmetic documentation)
 - #69825 (make `mem::discriminant` const)
 - #69859 (fix #62456)
 - #69891 (Exhaustiveness checking, `Matrix::push`: recursively expand or-patterns)
 - #69896 (parse: Tweak the function parameter edition check)

Failed merges:

r? @ghost
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/intrinsics.rs11
-rw-r--r--src/libcore/iter/adapters/mod.rs12
-rw-r--r--src/libcore/lib.rs2
-rw-r--r--src/libcore/mem/mod.rs9
-rw-r--r--src/libcore/num/mod.rs64
-rw-r--r--src/libcore/ops/arith.rs10
-rw-r--r--src/libcore/ops/mod.rs2
-rw-r--r--src/libcore/tests/lib.rs1
-rw-r--r--src/libcore/tests/mem.rs18
9 files changed, 105 insertions, 24 deletions
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index a889eff75c0..3c060cc6e84 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -1007,6 +1007,16 @@ extern "rust-intrinsic" {
     /// This will statically either panic, or do nothing.
     pub fn panic_if_uninhabited<T>();
 
+    /// A guard for unsafe functions that cannot ever be executed if `T` does not permit
+    /// zero-initialization: This will statically either panic, or do nothing.
+    #[cfg(not(bootstrap))]
+    pub fn panic_if_zero_invalid<T>();
+
+    /// A guard for unsafe functions that cannot ever be executed if `T` has invalid
+    /// bit patterns: This will statically either panic, or do nothing.
+    #[cfg(not(bootstrap))]
+    pub fn panic_if_any_invalid<T>();
+
     /// Gets a reference to a static `Location` indicating where it was called.
     #[rustc_const_unstable(feature = "const_caller_location", issue = "47809")]
     pub fn caller_location() -> &'static crate::panic::Location<'static>;
@@ -1852,6 +1862,7 @@ extern "rust-intrinsic" {
     ///
     /// The stabilized version of this intrinsic is
     /// [`std::mem::discriminant`](../../std/mem/fn.discriminant.html)
+    #[rustc_const_unstable(feature = "const_discriminant", issue = "69821")]
     pub fn discriminant_value<T>(v: &T) -> u64;
 
     /// Rust's "try catch" construct which invokes the function pointer `f` with
diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs
index 02dc9b8f82e..26132e36c97 100644
--- a/src/libcore/iter/adapters/mod.rs
+++ b/src/libcore/iter/adapters/mod.rs
@@ -200,6 +200,18 @@ where
     {
         self.it.fold(init, copy_fold(f))
     }
+
+    fn nth(&mut self, n: usize) -> Option<T> {
+        self.it.nth(n).copied()
+    }
+
+    fn last(self) -> Option<T> {
+        self.it.last().copied()
+    }
+
+    fn count(self) -> usize {
+        self.it.count()
+    }
 }
 
 #[stable(feature = "iter_copied", since = "1.36.0")]
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 81a3c419db8..a1dde1d51ef 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -72,6 +72,7 @@
 #![feature(concat_idents)]
 #![feature(const_ascii_ctype_on_intrinsics)]
 #![feature(const_alloc_layout)]
+#![feature(const_discriminant)]
 #![feature(const_if_match)]
 #![feature(const_loop)]
 #![feature(const_checked_int_methods)]
@@ -130,7 +131,6 @@
 #![feature(rtm_target_feature)]
 #![feature(f16c_target_feature)]
 #![feature(hexagon_target_feature)]
-#![feature(const_int_conversion)]
 #![feature(const_transmute)]
 #![feature(structural_match)]
 #![feature(abi_unadjusted)]
diff --git a/src/libcore/mem/mod.rs b/src/libcore/mem/mod.rs
index 90144d11dc9..7d9a8bcd05b 100644
--- a/src/libcore/mem/mod.rs
+++ b/src/libcore/mem/mod.rs
@@ -496,6 +496,9 @@ pub const fn needs_drop<T>() -> bool {
 #[allow(deprecated)]
 #[rustc_diagnostic_item = "mem_zeroed"]
 pub unsafe fn zeroed<T>() -> T {
+    #[cfg(not(bootstrap))]
+    intrinsics::panic_if_zero_invalid::<T>();
+    #[cfg(bootstrap)]
     intrinsics::panic_if_uninhabited::<T>();
     intrinsics::init()
 }
@@ -529,6 +532,9 @@ pub unsafe fn zeroed<T>() -> T {
 #[allow(deprecated)]
 #[rustc_diagnostic_item = "mem_uninitialized"]
 pub unsafe fn uninitialized<T>() -> T {
+    #[cfg(not(bootstrap))]
+    intrinsics::panic_if_any_invalid::<T>();
+    #[cfg(bootstrap)]
     intrinsics::panic_if_uninhabited::<T>();
     intrinsics::uninit()
 }
@@ -864,6 +870,7 @@ impl<T> fmt::Debug for Discriminant<T> {
 /// assert_ne!(mem::discriminant(&Foo::B(3)), mem::discriminant(&Foo::C(3)));
 /// ```
 #[stable(feature = "discriminant_value", since = "1.21.0")]
-pub fn discriminant<T>(v: &T) -> Discriminant<T> {
+#[rustc_const_unstable(feature = "const_discriminant", issue = "69821")]
+pub const fn discriminant<T>(v: &T) -> Discriminant<T> {
     Discriminant(intrinsics::discriminant_value(v), PhantomData)
 }
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 889ce2f211e..caffa6c509a 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -2154,7 +2154,7 @@ let bytes = ", $swap_op, stringify!($SelfT), ".to_be_bytes();
 assert_eq!(bytes, ", $be_bytes, ");
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
-            #[rustc_const_unstable(feature = "const_int_conversion", issue = "53718")]
+            #[rustc_const_stable(feature = "const_int_conversion", since = "1.43.0")]
             #[inline]
             pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
                 self.to_be().to_ne_bytes()
@@ -2174,7 +2174,7 @@ let bytes = ", $swap_op, stringify!($SelfT), ".to_le_bytes();
 assert_eq!(bytes, ", $le_bytes, ");
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
-            #[rustc_const_unstable(feature = "const_int_conversion", issue = "53718")]
+            #[rustc_const_stable(feature = "const_int_conversion", since = "1.43.0")]
             #[inline]
             pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
                 self.to_le().to_ne_bytes()
@@ -2209,12 +2209,20 @@ assert_eq!(
 );
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
-            #[rustc_const_unstable(feature = "const_int_conversion", issue = "53718")]
+            #[rustc_const_stable(feature = "const_int_conversion", since = "1.43.0")]
+            // SAFETY: const sound because integers are plain old datatypes so we can always
+            // transmute them to arrays of bytes
+            #[allow_internal_unstable(const_fn_union)]
             #[inline]
             pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
+                #[repr(C)]
+                union Bytes {
+                    val: $SelfT,
+                    bytes: [u8; mem::size_of::<$SelfT>()],
+                }
                 // SAFETY: integers are plain old datatypes so we can always transmute them to
                 // arrays of bytes
-                unsafe { mem::transmute(self) }
+                unsafe { Bytes { val: self }.bytes }
             }
         }
 
@@ -2243,7 +2251,7 @@ fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
 }
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
-            #[rustc_const_unstable(feature = "const_int_conversion", issue = "53718")]
+            #[rustc_const_stable(feature = "const_int_conversion", since = "1.43.0")]
             #[inline]
             pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                 Self::from_be(Self::from_ne_bytes(bytes))
@@ -2276,7 +2284,7 @@ fn read_le_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
 }
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
-            #[rustc_const_unstable(feature = "const_int_conversion", issue = "53718")]
+            #[rustc_const_stable(feature = "const_int_conversion", since = "1.43.0")]
             #[inline]
             pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                 Self::from_le(Self::from_ne_bytes(bytes))
@@ -2319,11 +2327,19 @@ fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
 }
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
-            #[rustc_const_unstable(feature = "const_int_conversion", issue = "53718")]
+            #[rustc_const_stable(feature = "const_int_conversion", since = "1.43.0")]
+            // SAFETY: const sound because integers are plain old datatypes so we can always
+            // transmute to them
+            #[allow_internal_unstable(const_fn_union)]
             #[inline]
             pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
+                #[repr(C)]
+                union Bytes {
+                    val: $SelfT,
+                    bytes: [u8; mem::size_of::<$SelfT>()],
+                }
                 // SAFETY: integers are plain old datatypes so we can always transmute to them
-                unsafe { mem::transmute(bytes) }
+                unsafe { Bytes { bytes }.val }
             }
         }
 
@@ -4099,7 +4115,7 @@ let bytes = ", $swap_op, stringify!($SelfT), ".to_be_bytes();
 assert_eq!(bytes, ", $be_bytes, ");
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
-            #[rustc_const_unstable(feature = "const_int_conversion", issue = "53718")]
+            #[rustc_const_stable(feature = "const_int_conversion", since = "1.43.0")]
             #[inline]
             pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
                 self.to_be().to_ne_bytes()
@@ -4119,7 +4135,7 @@ let bytes = ", $swap_op, stringify!($SelfT), ".to_le_bytes();
 assert_eq!(bytes, ", $le_bytes, ");
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
-            #[rustc_const_unstable(feature = "const_int_conversion", issue = "53718")]
+            #[rustc_const_stable(feature = "const_int_conversion", since = "1.43.0")]
             #[inline]
             pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
                 self.to_le().to_ne_bytes()
@@ -4154,12 +4170,20 @@ assert_eq!(
 );
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
-            #[rustc_const_unstable(feature = "const_int_conversion", issue = "53718")]
+            #[rustc_const_stable(feature = "const_int_conversion", since = "1.43.0")]
+            // SAFETY: const sound because integers are plain old datatypes so we can always
+            // transmute them to arrays of bytes
+            #[allow_internal_unstable(const_fn_union)]
             #[inline]
             pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
+                #[repr(C)]
+                union Bytes {
+                    val: $SelfT,
+                    bytes: [u8; mem::size_of::<$SelfT>()],
+                }
                 // SAFETY: integers are plain old datatypes so we can always transmute them to
                 // arrays of bytes
-                unsafe { mem::transmute(self) }
+                unsafe { Bytes { val: self }.bytes }
             }
         }
 
@@ -4188,7 +4212,7 @@ fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
 }
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
-            #[rustc_const_unstable(feature = "const_int_conversion", issue = "53718")]
+            #[rustc_const_stable(feature = "const_int_conversion", since = "1.43.0")]
             #[inline]
             pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                 Self::from_be(Self::from_ne_bytes(bytes))
@@ -4221,7 +4245,7 @@ fn read_le_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
 }
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
-            #[rustc_const_unstable(feature = "const_int_conversion", issue = "53718")]
+            #[rustc_const_stable(feature = "const_int_conversion", since = "1.43.0")]
             #[inline]
             pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                 Self::from_le(Self::from_ne_bytes(bytes))
@@ -4264,11 +4288,19 @@ fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
 }
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
-            #[rustc_const_unstable(feature = "const_int_conversion", issue = "53718")]
+            #[rustc_const_stable(feature = "const_int_conversion", since = "1.43.0")]
+            // SAFETY: const sound because integers are plain old datatypes so we can always
+            // transmute to them
+            #[allow_internal_unstable(const_fn_union)]
             #[inline]
             pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
+                #[repr(C)]
+                union Bytes {
+                    val: $SelfT,
+                    bytes: [u8; mem::size_of::<$SelfT>()],
+                }
                 // SAFETY: integers are plain old datatypes so we can always transmute to them
-                unsafe { mem::transmute(bytes) }
+                unsafe { Bytes { bytes }.val }
             }
         }
 
diff --git a/src/libcore/ops/arith.rs b/src/libcore/ops/arith.rs
index 59a72799e25..e9ec81394e3 100644
--- a/src/libcore/ops/arith.rs
+++ b/src/libcore/ops/arith.rs
@@ -13,7 +13,7 @@
 /// ```
 /// use std::ops::Add;
 ///
-/// #[derive(Debug, PartialEq)]
+/// #[derive(Debug, Copy, Clone, PartialEq)]
 /// struct Point {
 ///     x: i32,
 ///     y: i32,
@@ -42,7 +42,7 @@
 /// ```
 /// use std::ops::Add;
 ///
-/// #[derive(Debug, PartialEq)]
+/// #[derive(Debug, Copy, Clone, PartialEq)]
 /// struct Point<T> {
 ///     x: T,
 ///     y: T,
@@ -115,7 +115,7 @@ add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 /// ```
 /// use std::ops::Sub;
 ///
-/// #[derive(Debug, PartialEq)]
+/// #[derive(Debug, Copy, Clone, PartialEq)]
 /// struct Point {
 ///     x: i32,
 ///     y: i32,
@@ -657,7 +657,7 @@ neg_impl_numeric! { isize i8 i16 i32 i64 i128 f32 f64 }
 /// ```
 /// use std::ops::AddAssign;
 ///
-/// #[derive(Debug, PartialEq)]
+/// #[derive(Debug, Copy, Clone, PartialEq)]
 /// struct Point {
 ///     x: i32,
 ///     y: i32,
@@ -715,7 +715,7 @@ add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 /// ```
 /// use std::ops::SubAssign;
 ///
-/// #[derive(Debug, PartialEq)]
+/// #[derive(Debug, Copy, Clone, PartialEq)]
 /// struct Point {
 ///     x: i32,
 ///     y: i32,
diff --git a/src/libcore/ops/mod.rs b/src/libcore/ops/mod.rs
index 77b92b6ccbd..e3e5934b44b 100644
--- a/src/libcore/ops/mod.rs
+++ b/src/libcore/ops/mod.rs
@@ -42,7 +42,7 @@
 //! ```rust
 //! use std::ops::{Add, Sub};
 //!
-//! #[derive(Debug, PartialEq)]
+//! #[derive(Debug, Copy, Clone, PartialEq)]
 //! struct Point {
 //!     x: i32,
 //!     y: i32,
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index 71a061af289..05f958cbe81 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -41,6 +41,7 @@
 #![feature(never_type)]
 #![feature(unwrap_infallible)]
 #![feature(leading_trailing_ones)]
+#![feature(const_forget)]
 
 extern crate test;
 
diff --git a/src/libcore/tests/mem.rs b/src/libcore/tests/mem.rs
index 59588d97787..8337ab10341 100644
--- a/src/libcore/tests/mem.rs
+++ b/src/libcore/tests/mem.rs
@@ -129,3 +129,21 @@ fn test_discriminant_send_sync() {
     is_send_sync::<Discriminant<Regular>>();
     is_send_sync::<Discriminant<NotSendSync>>();
 }
+
+#[test]
+fn test_const_forget() {
+    const _: () = forget(0i32);
+    const _: () = forget(Vec::<Vec<Box<i32>>>::new());
+
+    // Writing this function signature without const-forget
+    // triggers compiler errors:
+    // 1) That we use a non-const fn inside a const fn
+    // 2) without the forget, it complains about the destructor of Box
+    const fn const_forget_box<T>(x: Box<T>) {
+        forget(x);
+    }
+
+    // Call the forget_box at runtime,
+    // as we can't const-construct a box yet.
+    const_forget_box(Box::new(0i32));
+}