From 62722735fb62c2f93656a012c29310155de35467 Mon Sep 17 00:00:00 2001
From: Joshua Nelson <jyn514@gmail.com>
Date: Fri, 31 Jan 2020 00:30:55 -0500
Subject: [PATCH 01/12] impl From<[T; N]> for Vec<T>

---
 src/liballoc/vec.rs | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index f661b83042868..c8ff4a41536fd 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -2397,6 +2397,13 @@ impl<T: Clone> From<&mut [T]> for Vec<T> {
     }
 }
 
+#[stable(feature = "vec_from_array", since = "1.42.0")]
+impl<T, const N: usize> From<[T; N]> for Vec<T> {
+    fn from(arr: [T; N]) -> Vec<T> {
+        <[T]>::into_vec(box arr)
+    }
+}
+
 #[stable(feature = "vec_from_cow_slice", since = "1.14.0")]
 impl<'a, T> From<Cow<'a, [T]>> for Vec<T>
 where

From daeb8ece8c930174baa874aa3f2f278fbec9637d Mon Sep 17 00:00:00 2001
From: Joshua Nelson <jyn514@gmail.com>
Date: Fri, 31 Jan 2020 10:46:08 -0500
Subject: [PATCH 02/12] fix error compiling stage2

Co-Authored-By: lzutao <taolzu@gmail.com>
---
 src/liballoc/vec.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index c8ff4a41536fd..f557d056dc8a6 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -2399,7 +2399,7 @@ impl<T: Clone> From<&mut [T]> for Vec<T> {
 
 #[stable(feature = "vec_from_array", since = "1.42.0")]
 impl<T, const N: usize> From<[T; N]> for Vec<T> {
-    fn from(arr: [T; N]) -> Vec<T> {
+    fn from(arr: [T; N]) -> Self {
         <[T]>::into_vec(box arr)
     }
 }

From f267d9dc191debfef74cc211dbca3d286b51f761 Mon Sep 17 00:00:00 2001
From: Joshua Nelson <jyn514@gmail.com>
Date: Fri, 31 Jan 2020 11:41:19 -0500
Subject: [PATCH 03/12] limit From impl to LengthAtMost32

Co-Authored-By: Mazdak Farrokhzad <twingoow@gmail.com>
---
 src/liballoc/vec.rs | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index f557d056dc8a6..8fede31847cd9 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -2398,7 +2398,10 @@ impl<T: Clone> From<&mut [T]> for Vec<T> {
 }
 
 #[stable(feature = "vec_from_array", since = "1.42.0")]
-impl<T, const N: usize> From<[T; N]> for Vec<T> {
+impl<T, const N: usize> From<[T; N]> for Vec<T>
+where
+    [T; N]: LengthAtMost32,
+{
     fn from(arr: [T; N]) -> Self {
         <[T]>::into_vec(box arr)
     }

From e3d5eaf2bba89db8359393ac7656db19cb421fb5 Mon Sep 17 00:00:00 2001
From: Joshua Nelson <jyn514@gmail.com>
Date: Fri, 31 Jan 2020 11:44:58 -0500
Subject: [PATCH 04/12] add ui-tests

---
 .../array-impls/alloc-traits-impls-length-32.rs              | 4 ++++
 .../array-impls/alloc-types-no-impls-length-33.rs            | 5 +++++
 2 files changed, 9 insertions(+)

diff --git a/src/test/ui/const-generics/array-impls/alloc-traits-impls-length-32.rs b/src/test/ui/const-generics/array-impls/alloc-traits-impls-length-32.rs
index db941a440e104..0d0765e971d50 100644
--- a/src/test/ui/const-generics/array-impls/alloc-traits-impls-length-32.rs
+++ b/src/test/ui/const-generics/array-impls/alloc-traits-impls-length-32.rs
@@ -14,6 +14,10 @@ where
     Vec::<A>::new()
 }
 
+pub fn yes_array_into_vec<T>() -> Vec<T> {
+    [].into()
+}
+
 use std::collections::VecDeque;
 
 pub fn yes_vecdeque_partial_eq_array<A, B>() -> impl PartialEq<[B; 32]>
diff --git a/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.rs b/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.rs
index 3a23b9b5832c0..92dff7e07928c 100644
--- a/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.rs
+++ b/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.rs
@@ -2,6 +2,11 @@
 
 use std::{convert::TryFrom, rc::Rc, sync::Arc};
 
+pub fn no_vec() {
+    let v: Vec<_> = [0; 33].into();
+    //~^ ERROR the trait bound `std::vec::Vec<u8>: std::convert::From<[u8; 33]>` is not satisfied
+}
+
 pub fn no_box() {
     let boxed_slice = Box::new([0; 33]) as Box<[i32]>;
     let boxed_array = <Box<[i32; 33]>>::try_from(boxed_slice);

From ba46b61bbcd0d2860105c429cf73254c388e9118 Mon Sep 17 00:00:00 2001
From: Joshua Nelson <jyn514@gmail.com>
Date: Fri, 31 Jan 2020 13:59:57 -0500
Subject: [PATCH 05/12] bless UI tests

---
 .../alloc-types-no-impls-length-33.rs         |  2 +-
 .../alloc-types-no-impls-length-33.stderr     | 23 +++++++++++++------
 2 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.rs b/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.rs
index 92dff7e07928c..4b195f3a06edc 100644
--- a/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.rs
+++ b/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.rs
@@ -4,7 +4,7 @@ use std::{convert::TryFrom, rc::Rc, sync::Arc};
 
 pub fn no_vec() {
     let v: Vec<_> = [0; 33].into();
-    //~^ ERROR the trait bound `std::vec::Vec<u8>: std::convert::From<[u8; 33]>` is not satisfied
+    //~^ ERROR arrays only have std trait implementations for lengths 0..=32
 }
 
 pub fn no_box() {
diff --git a/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.stderr b/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.stderr
index 193fb4c4374a4..d795840551c50 100644
--- a/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.stderr
+++ b/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.stderr
@@ -1,5 +1,14 @@
+error[E0277]: arrays only have std trait implementations for lengths 0..=32
+  --> $DIR/alloc-types-no-impls-length-33.rs:6:29
+   |
+LL |     let v: Vec<_> = [0; 33].into();
+   |                             ^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[{integer}; 33]`
+   |
+   = note: required because of the requirements on the impl of `std::convert::From<[{integer}; 33]>` for `std::vec::Vec<{integer}>`
+   = note: required because of the requirements on the impl of `std::convert::Into<std::vec::Vec<{integer}>>` for `[{integer}; 33]`
+
 error[E0277]: the trait bound `std::boxed::Box<[i32; 33]>: std::convert::From<std::boxed::Box<[i32]>>` is not satisfied
-  --> $DIR/alloc-types-no-impls-length-33.rs:7:23
+  --> $DIR/alloc-types-no-impls-length-33.rs:12:23
    |
 LL |     let boxed_array = <Box<[i32; 33]>>::try_from(boxed_slice);
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<std::boxed::Box<[i32]>>` is not implemented for `std::boxed::Box<[i32; 33]>`
@@ -14,7 +23,7 @@ LL |     let boxed_array = <Box<[i32; 33]>>::try_from(boxed_slice);
    = note: required because of the requirements on the impl of `std::convert::TryFrom<std::boxed::Box<[i32]>>` for `std::boxed::Box<[i32; 33]>`
 
 error[E0277]: the trait bound `std::boxed::Box<[i32; 33]>: std::convert::TryFrom<std::boxed::Box<[i32]>>` is not satisfied
-  --> $DIR/alloc-types-no-impls-length-33.rs:7:23
+  --> $DIR/alloc-types-no-impls-length-33.rs:12:23
    |
 LL |     let boxed_array = <Box<[i32; 33]>>::try_from(boxed_slice);
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::TryFrom<std::boxed::Box<[i32]>>` is not implemented for `std::boxed::Box<[i32; 33]>`
@@ -23,7 +32,7 @@ LL |     let boxed_array = <Box<[i32; 33]>>::try_from(boxed_slice);
              <std::boxed::Box<[T; _]> as std::convert::TryFrom<std::boxed::Box<[T]>>>
 
 error[E0277]: the trait bound `std::rc::Rc<[i32; 33]>: std::convert::From<std::rc::Rc<[i32]>>` is not satisfied
-  --> $DIR/alloc-types-no-impls-length-33.rs:14:23
+  --> $DIR/alloc-types-no-impls-length-33.rs:19:23
    |
 LL |     let boxed_array = <Rc<[i32; 33]>>::try_from(boxed_slice);
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<std::rc::Rc<[i32]>>` is not implemented for `std::rc::Rc<[i32; 33]>`
@@ -38,7 +47,7 @@ LL |     let boxed_array = <Rc<[i32; 33]>>::try_from(boxed_slice);
    = note: required because of the requirements on the impl of `std::convert::TryFrom<std::rc::Rc<[i32]>>` for `std::rc::Rc<[i32; 33]>`
 
 error[E0277]: the trait bound `std::rc::Rc<[i32; 33]>: std::convert::TryFrom<std::rc::Rc<[i32]>>` is not satisfied
-  --> $DIR/alloc-types-no-impls-length-33.rs:14:23
+  --> $DIR/alloc-types-no-impls-length-33.rs:19:23
    |
 LL |     let boxed_array = <Rc<[i32; 33]>>::try_from(boxed_slice);
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::TryFrom<std::rc::Rc<[i32]>>` is not implemented for `std::rc::Rc<[i32; 33]>`
@@ -47,7 +56,7 @@ LL |     let boxed_array = <Rc<[i32; 33]>>::try_from(boxed_slice);
              <std::rc::Rc<[T; _]> as std::convert::TryFrom<std::rc::Rc<[T]>>>
 
 error[E0277]: the trait bound `std::sync::Arc<[i32; 33]>: std::convert::From<std::sync::Arc<[i32]>>` is not satisfied
-  --> $DIR/alloc-types-no-impls-length-33.rs:21:23
+  --> $DIR/alloc-types-no-impls-length-33.rs:26:23
    |
 LL |     let boxed_array = <Arc<[i32; 33]>>::try_from(boxed_slice);
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<std::sync::Arc<[i32]>>` is not implemented for `std::sync::Arc<[i32; 33]>`
@@ -62,7 +71,7 @@ LL |     let boxed_array = <Arc<[i32; 33]>>::try_from(boxed_slice);
    = note: required because of the requirements on the impl of `std::convert::TryFrom<std::sync::Arc<[i32]>>` for `std::sync::Arc<[i32; 33]>`
 
 error[E0277]: the trait bound `std::sync::Arc<[i32; 33]>: std::convert::TryFrom<std::sync::Arc<[i32]>>` is not satisfied
-  --> $DIR/alloc-types-no-impls-length-33.rs:21:23
+  --> $DIR/alloc-types-no-impls-length-33.rs:26:23
    |
 LL |     let boxed_array = <Arc<[i32; 33]>>::try_from(boxed_slice);
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::TryFrom<std::sync::Arc<[i32]>>` is not implemented for `std::sync::Arc<[i32; 33]>`
@@ -70,6 +79,6 @@ LL |     let boxed_array = <Arc<[i32; 33]>>::try_from(boxed_slice);
    = help: the following implementations were found:
              <std::sync::Arc<[T; _]> as std::convert::TryFrom<std::sync::Arc<[T]>>>
 
-error: aborting due to 6 previous errors
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0277`.

From 96794d86f127dd409760765a64a36c07d9ed585f Mon Sep 17 00:00:00 2001
From: Joshua Nelson <jyn514@gmail.com>
Date: Sat, 1 Feb 2020 13:15:50 +0000
Subject: [PATCH 06/12] fix test failure

---
 src/liballoc/vec.rs | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index 8fede31847cd9..d5339453f8173 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -2402,8 +2402,13 @@ impl<T, const N: usize> From<[T; N]> for Vec<T>
 where
     [T; N]: LengthAtMost32,
 {
-    fn from(arr: [T; N]) -> Self {
-        <[T]>::into_vec(box arr)
+    #[cfg(not(test))]
+    fn from(s: [T; N]) -> Vec<T> {
+        (box s as Box<[T]>).into_vec()
+    }
+    #[cfg(test)]
+    fn from(s: [T; N]) -> Vec<T> {
+        crate::slice::into_vec(box s)
     }
 }
 

From 1ac4a461425b7a2e29aeb3c2b2cae944f8cbcc77 Mon Sep 17 00:00:00 2001
From: Joshua Nelson <jyn514@gmail.com>
Date: Sat, 1 Feb 2020 13:35:26 +0000
Subject: [PATCH 07/12] make the impl a little prettier

---
 src/liballoc/vec.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index d5339453f8173..921c042795902 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -2404,7 +2404,7 @@ where
 {
     #[cfg(not(test))]
     fn from(s: [T; N]) -> Vec<T> {
-        (box s as Box<[T]>).into_vec()
+        <[T]>::into_vec(box s)
     }
     #[cfg(test)]
     fn from(s: [T; N]) -> Vec<T> {

From 8212584c9ecdbd91736fc7a480fe3b7409b73477 Mon Sep 17 00:00:00 2001
From: Joshua Nelson <jyn514@gmail.com>
Date: Tue, 10 Mar 2020 23:13:56 +0000
Subject: [PATCH 08/12] Bump release cutoff

---
 src/liballoc/vec.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index 921c042795902..9f30ca29c0386 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -2397,7 +2397,7 @@ impl<T: Clone> From<&mut [T]> for Vec<T> {
     }
 }
 
-#[stable(feature = "vec_from_array", since = "1.42.0")]
+#[stable(feature = "vec_from_array", since = "1.44.0")]
 impl<T, const N: usize> From<[T; N]> for Vec<T>
 where
     [T; N]: LengthAtMost32,

From 3477e67a92878adae48b975915cb7a5c21026cd4 Mon Sep 17 00:00:00 2001
From: Joshua Nelson <jyn514@gmail.com>
Date: Tue, 10 Mar 2020 23:49:45 +0000
Subject: [PATCH 09/12] Allow vec.rs to be over 3000 lines :(

---
 src/liballoc/vec.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index 9f30ca29c0386..b9bd0dd8a1ea5 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -1,3 +1,4 @@
+// ignore-tidy-filelength
 //! A contiguous growable array type with heap-allocated contents, written
 //! `Vec<T>`.
 //!

From 7fdc3efb7ad6e9f73110f8e2e01120cd022b5fc9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= <tomasz.miasko@gmail.com>
Date: Wed, 18 Mar 2020 00:00:00 +0000
Subject: [PATCH 10/12] Add copy bound to atomic intrinsics

---
 src/libcore/intrinsics.rs | 162 +++++++++++++++++++-------------------
 1 file changed, 81 insertions(+), 81 deletions(-)

diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index f7ecbd80cbcdc..47ac08e2f1095 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -76,7 +76,7 @@ extern "rust-intrinsic" {
     /// [`AtomicBool::compare_exchange`][compare_exchange].
     ///
     /// [compare_exchange]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange
-    pub fn atomic_cxchg<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchg<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -86,7 +86,7 @@ extern "rust-intrinsic" {
     /// [`AtomicBool::compare_exchange`][compare_exchange].
     ///
     /// [compare_exchange]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange
-    pub fn atomic_cxchg_acq<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchg_acq<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -98,7 +98,7 @@ extern "rust-intrinsic" {
     /// [`AtomicBool::compare_exchange`][compare_exchange].
     ///
     /// [compare_exchange]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange
-    pub fn atomic_cxchg_rel<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchg_rel<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -110,7 +110,7 @@ extern "rust-intrinsic" {
     /// [`AtomicBool::compare_exchange`][compare_exchange].
     ///
     /// [compare_exchange]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange
-    pub fn atomic_cxchg_acqrel<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchg_acqrel<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -120,7 +120,7 @@ extern "rust-intrinsic" {
     /// [`AtomicBool::compare_exchange`][compare_exchange].
     ///
     /// [compare_exchange]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange
-    pub fn atomic_cxchg_relaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchg_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -132,7 +132,7 @@ extern "rust-intrinsic" {
     /// [`AtomicBool::compare_exchange`][compare_exchange].
     ///
     /// [compare_exchange]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange
-    pub fn atomic_cxchg_failrelaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchg_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -144,7 +144,7 @@ extern "rust-intrinsic" {
     /// [`AtomicBool::compare_exchange`][compare_exchange].
     ///
     /// [compare_exchange]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange
-    pub fn atomic_cxchg_failacq<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchg_failacq<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -156,7 +156,7 @@ extern "rust-intrinsic" {
     /// [`AtomicBool::compare_exchange`][compare_exchange].
     ///
     /// [compare_exchange]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange
-    pub fn atomic_cxchg_acq_failrelaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchg_acq_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -168,7 +168,7 @@ extern "rust-intrinsic" {
     /// [`AtomicBool::compare_exchange`][compare_exchange].
     ///
     /// [compare_exchange]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange
-    pub fn atomic_cxchg_acqrel_failrelaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchg_acqrel_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 
     /// Stores a value if the current value is the same as the `old` value.
     ///
@@ -179,7 +179,7 @@ extern "rust-intrinsic" {
     /// [`AtomicBool::compare_exchange_weak`][cew].
     ///
     /// [cew]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak
-    pub fn atomic_cxchgweak<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchgweak<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -189,7 +189,7 @@ extern "rust-intrinsic" {
     /// [`AtomicBool::compare_exchange_weak`][cew].
     ///
     /// [cew]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak
-    pub fn atomic_cxchgweak_acq<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchgweak_acq<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -201,7 +201,7 @@ extern "rust-intrinsic" {
     /// [`AtomicBool::compare_exchange_weak`][cew].
     ///
     /// [cew]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak
-    pub fn atomic_cxchgweak_rel<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchgweak_rel<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -213,7 +213,7 @@ extern "rust-intrinsic" {
     /// [`AtomicBool::compare_exchange_weak`][cew].
     ///
     /// [cew]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak
-    pub fn atomic_cxchgweak_acqrel<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchgweak_acqrel<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -223,7 +223,7 @@ extern "rust-intrinsic" {
     /// [`AtomicBool::compare_exchange_weak`][cew].
     ///
     /// [cew]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak
-    pub fn atomic_cxchgweak_relaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchgweak_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -235,7 +235,7 @@ extern "rust-intrinsic" {
     /// [`AtomicBool::compare_exchange_weak`][cew].
     ///
     /// [cew]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak
-    pub fn atomic_cxchgweak_failrelaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchgweak_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -247,7 +247,7 @@ extern "rust-intrinsic" {
     /// [`AtomicBool::compare_exchange_weak`][cew].
     ///
     /// [cew]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak
-    pub fn atomic_cxchgweak_failacq<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchgweak_failacq<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -259,7 +259,7 @@ extern "rust-intrinsic" {
     /// [`AtomicBool::compare_exchange_weak`][cew].
     ///
     /// [cew]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak
-    pub fn atomic_cxchgweak_acq_failrelaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchgweak_acq_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -271,7 +271,7 @@ extern "rust-intrinsic" {
     /// [`AtomicBool::compare_exchange_weak`][cew].
     ///
     /// [cew]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak
-    pub fn atomic_cxchgweak_acqrel_failrelaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchgweak_acqrel_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 
     /// Loads the current value of the pointer.
     ///
@@ -280,7 +280,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::SeqCst`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::load`](../../std/sync/atomic/struct.AtomicBool.html#method.load).
-    pub fn atomic_load<T>(src: *const T) -> T;
+    pub fn atomic_load<T: Copy>(src: *const T) -> T;
     /// Loads the current value of the pointer.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -288,7 +288,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Acquire`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::load`](../../std/sync/atomic/struct.AtomicBool.html#method.load).
-    pub fn atomic_load_acq<T>(src: *const T) -> T;
+    pub fn atomic_load_acq<T: Copy>(src: *const T) -> T;
     /// Loads the current value of the pointer.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -296,8 +296,8 @@ extern "rust-intrinsic" {
     /// [`Ordering::Relaxed`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::load`](../../std/sync/atomic/struct.AtomicBool.html#method.load).
-    pub fn atomic_load_relaxed<T>(src: *const T) -> T;
-    pub fn atomic_load_unordered<T>(src: *const T) -> T;
+    pub fn atomic_load_relaxed<T: Copy>(src: *const T) -> T;
+    pub fn atomic_load_unordered<T: Copy>(src: *const T) -> T;
 
     /// Stores the value at the specified memory location.
     ///
@@ -306,7 +306,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::SeqCst`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::store`](../../std/sync/atomic/struct.AtomicBool.html#method.store).
-    pub fn atomic_store<T>(dst: *mut T, val: T);
+    pub fn atomic_store<T: Copy>(dst: *mut T, val: T);
     /// Stores the value at the specified memory location.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -314,7 +314,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Release`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::store`](../../std/sync/atomic/struct.AtomicBool.html#method.store).
-    pub fn atomic_store_rel<T>(dst: *mut T, val: T);
+    pub fn atomic_store_rel<T: Copy>(dst: *mut T, val: T);
     /// Stores the value at the specified memory location.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -322,8 +322,8 @@ extern "rust-intrinsic" {
     /// [`Ordering::Relaxed`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::store`](../../std/sync/atomic/struct.AtomicBool.html#method.store).
-    pub fn atomic_store_relaxed<T>(dst: *mut T, val: T);
-    pub fn atomic_store_unordered<T>(dst: *mut T, val: T);
+    pub fn atomic_store_relaxed<T: Copy>(dst: *mut T, val: T);
+    pub fn atomic_store_unordered<T: Copy>(dst: *mut T, val: T);
 
     /// Stores the value at the specified memory location, returning the old value.
     ///
@@ -332,7 +332,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::SeqCst`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::swap`](../../std/sync/atomic/struct.AtomicBool.html#method.swap).
-    pub fn atomic_xchg<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xchg<T: Copy>(dst: *mut T, src: T) -> T;
     /// Stores the value at the specified memory location, returning the old value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -340,7 +340,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Acquire`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::swap`](../../std/sync/atomic/struct.AtomicBool.html#method.swap).
-    pub fn atomic_xchg_acq<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xchg_acq<T: Copy>(dst: *mut T, src: T) -> T;
     /// Stores the value at the specified memory location, returning the old value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -348,7 +348,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Release`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::swap`](../../std/sync/atomic/struct.AtomicBool.html#method.swap).
-    pub fn atomic_xchg_rel<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xchg_rel<T: Copy>(dst: *mut T, src: T) -> T;
     /// Stores the value at the specified memory location, returning the old value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -356,7 +356,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::AcqRel`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::swap`](../../std/sync/atomic/struct.AtomicBool.html#method.swap).
-    pub fn atomic_xchg_acqrel<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xchg_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
     /// Stores the value at the specified memory location, returning the old value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -364,7 +364,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Relaxed`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::swap`](../../std/sync/atomic/struct.AtomicBool.html#method.swap).
-    pub fn atomic_xchg_relaxed<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xchg_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
     /// Adds to the current value, returning the previous value.
     ///
@@ -373,7 +373,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::SeqCst`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicIsize::fetch_add`](../../std/sync/atomic/struct.AtomicIsize.html#method.fetch_add).
-    pub fn atomic_xadd<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xadd<T: Copy>(dst: *mut T, src: T) -> T;
     /// Adds to the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -381,7 +381,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Acquire`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicIsize::fetch_add`](../../std/sync/atomic/struct.AtomicIsize.html#method.fetch_add).
-    pub fn atomic_xadd_acq<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xadd_acq<T: Copy>(dst: *mut T, src: T) -> T;
     /// Adds to the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -389,7 +389,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Release`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicIsize::fetch_add`](../../std/sync/atomic/struct.AtomicIsize.html#method.fetch_add).
-    pub fn atomic_xadd_rel<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xadd_rel<T: Copy>(dst: *mut T, src: T) -> T;
     /// Adds to the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -397,7 +397,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::AcqRel`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicIsize::fetch_add`](../../std/sync/atomic/struct.AtomicIsize.html#method.fetch_add).
-    pub fn atomic_xadd_acqrel<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xadd_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
     /// Adds to the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -405,7 +405,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Relaxed`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicIsize::fetch_add`](../../std/sync/atomic/struct.AtomicIsize.html#method.fetch_add).
-    pub fn atomic_xadd_relaxed<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xadd_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
     /// Subtract from the current value, returning the previous value.
     ///
@@ -414,7 +414,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::SeqCst`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicIsize::fetch_sub`](../../std/sync/atomic/struct.AtomicIsize.html#method.fetch_sub).
-    pub fn atomic_xsub<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xsub<T: Copy>(dst: *mut T, src: T) -> T;
     /// Subtract from the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -422,7 +422,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Acquire`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicIsize::fetch_sub`](../../std/sync/atomic/struct.AtomicIsize.html#method.fetch_sub).
-    pub fn atomic_xsub_acq<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xsub_acq<T: Copy>(dst: *mut T, src: T) -> T;
     /// Subtract from the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -430,7 +430,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Release`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicIsize::fetch_sub`](../../std/sync/atomic/struct.AtomicIsize.html#method.fetch_sub).
-    pub fn atomic_xsub_rel<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xsub_rel<T: Copy>(dst: *mut T, src: T) -> T;
     /// Subtract from the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -438,7 +438,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::AcqRel`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicIsize::fetch_sub`](../../std/sync/atomic/struct.AtomicIsize.html#method.fetch_sub).
-    pub fn atomic_xsub_acqrel<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xsub_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
     /// Subtract from the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -446,7 +446,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Relaxed`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicIsize::fetch_sub`](../../std/sync/atomic/struct.AtomicIsize.html#method.fetch_sub).
-    pub fn atomic_xsub_relaxed<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xsub_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
     /// Bitwise and with the current value, returning the previous value.
     ///
@@ -455,7 +455,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::SeqCst`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::fetch_and`](../../std/sync/atomic/struct.AtomicBool.html#method.fetch_and).
-    pub fn atomic_and<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_and<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise and with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -463,7 +463,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Acquire`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::fetch_and`](../../std/sync/atomic/struct.AtomicBool.html#method.fetch_and).
-    pub fn atomic_and_acq<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_and_acq<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise and with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -471,7 +471,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Release`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::fetch_and`](../../std/sync/atomic/struct.AtomicBool.html#method.fetch_and).
-    pub fn atomic_and_rel<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_and_rel<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise and with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -479,7 +479,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::AcqRel`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::fetch_and`](../../std/sync/atomic/struct.AtomicBool.html#method.fetch_and).
-    pub fn atomic_and_acqrel<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_and_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise and with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -487,7 +487,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Relaxed`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::fetch_and`](../../std/sync/atomic/struct.AtomicBool.html#method.fetch_and).
-    pub fn atomic_and_relaxed<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_and_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
     /// Bitwise nand with the current value, returning the previous value.
     ///
@@ -496,7 +496,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::SeqCst`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::fetch_nand`](../../std/sync/atomic/struct.AtomicBool.html#method.fetch_nand).
-    pub fn atomic_nand<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_nand<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise nand with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -504,7 +504,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Acquire`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::fetch_nand`](../../std/sync/atomic/struct.AtomicBool.html#method.fetch_nand).
-    pub fn atomic_nand_acq<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_nand_acq<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise nand with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -512,7 +512,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Release`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::fetch_nand`](../../std/sync/atomic/struct.AtomicBool.html#method.fetch_nand).
-    pub fn atomic_nand_rel<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_nand_rel<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise nand with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -520,7 +520,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::AcqRel`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::fetch_nand`](../../std/sync/atomic/struct.AtomicBool.html#method.fetch_nand).
-    pub fn atomic_nand_acqrel<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_nand_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise nand with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -528,7 +528,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Relaxed`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::fetch_nand`](../../std/sync/atomic/struct.AtomicBool.html#method.fetch_nand).
-    pub fn atomic_nand_relaxed<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_nand_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
     /// Bitwise or with the current value, returning the previous value.
     ///
@@ -537,7 +537,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::SeqCst`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::fetch_or`](../../std/sync/atomic/struct.AtomicBool.html#method.fetch_or).
-    pub fn atomic_or<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_or<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise or with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -545,7 +545,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Acquire`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::fetch_or`](../../std/sync/atomic/struct.AtomicBool.html#method.fetch_or).
-    pub fn atomic_or_acq<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_or_acq<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise or with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -553,7 +553,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Release`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::fetch_or`](../../std/sync/atomic/struct.AtomicBool.html#method.fetch_or).
-    pub fn atomic_or_rel<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_or_rel<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise or with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -561,7 +561,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::AcqRel`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::fetch_or`](../../std/sync/atomic/struct.AtomicBool.html#method.fetch_or).
-    pub fn atomic_or_acqrel<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_or_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise or with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -569,7 +569,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Relaxed`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::fetch_or`](../../std/sync/atomic/struct.AtomicBool.html#method.fetch_or).
-    pub fn atomic_or_relaxed<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_or_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
     /// Bitwise xor with the current value, returning the previous value.
     ///
@@ -578,7 +578,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::SeqCst`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::fetch_xor`](../../std/sync/atomic/struct.AtomicBool.html#method.fetch_xor).
-    pub fn atomic_xor<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xor<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise xor with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -586,7 +586,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Acquire`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::fetch_xor`](../../std/sync/atomic/struct.AtomicBool.html#method.fetch_xor).
-    pub fn atomic_xor_acq<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xor_acq<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise xor with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -594,7 +594,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Release`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::fetch_xor`](../../std/sync/atomic/struct.AtomicBool.html#method.fetch_xor).
-    pub fn atomic_xor_rel<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xor_rel<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise xor with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -602,7 +602,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::AcqRel`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::fetch_xor`](../../std/sync/atomic/struct.AtomicBool.html#method.fetch_xor).
-    pub fn atomic_xor_acqrel<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xor_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise xor with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -610,7 +610,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Relaxed`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `order`. For example,
     /// [`AtomicBool::fetch_xor`](../../std/sync/atomic/struct.AtomicBool.html#method.fetch_xor).
-    pub fn atomic_xor_relaxed<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xor_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
     /// Maximum with the current value using a signed comparison.
     ///
@@ -619,7 +619,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::SeqCst`](../../std/sync/atomic/enum.Ordering.html#variant.SeqCst)
     /// as the `order`. For example,
     /// [`AtomicI32::fetch_max`](../../std/sync/atomic/struct.AtomicI32.html#method.fetch_max).
-    pub fn atomic_max<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_max<T: Copy>(dst: *mut T, src: T) -> T;
     /// Maximum with the current value using a signed comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -627,7 +627,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Acquire`](../../std/sync/atomic/enum.Ordering.html#variant.Acquire)
     /// as the `order`. For example,
     /// [`AtomicI32::fetch_max`](../../std/sync/atomic/struct.AtomicI32.html#method.fetch_max).
-    pub fn atomic_max_acq<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_max_acq<T: Copy>(dst: *mut T, src: T) -> T;
     /// Maximum with the current value using a signed comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -635,7 +635,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Release`](../../std/sync/atomic/enum.Ordering.html#variant.Release)
     /// as the `order`. For example,
     /// [`AtomicI32::fetch_max`](../../std/sync/atomic/struct.AtomicI32.html#method.fetch_max).
-    pub fn atomic_max_rel<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_max_rel<T: Copy>(dst: *mut T, src: T) -> T;
     /// Maximum with the current value using a signed comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -643,7 +643,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::AcqRel`](../../std/sync/atomic/enum.Ordering.html#variant.AcqRel)
     /// as the `order`. For example,
     /// [`AtomicI32::fetch_max`](../../std/sync/atomic/struct.AtomicI32.html#method.fetch_max).
-    pub fn atomic_max_acqrel<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_max_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
     /// Maximum with the current value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -651,7 +651,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Relaxed`](../../std/sync/atomic/enum.Ordering.html#variant.Relaxed)
     /// as the `order`. For example,
     /// [`AtomicI32::fetch_max`](../../std/sync/atomic/struct.AtomicI32.html#method.fetch_max).
-    pub fn atomic_max_relaxed<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_max_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
     /// Minimum with the current value using a signed comparison.
     ///
@@ -660,7 +660,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::SeqCst`](../../std/sync/atomic/enum.Ordering.html#variant.SeqCst)
     /// as the `order`. For example,
     /// [`AtomicI32::fetch_min`](../../std/sync/atomic/struct.AtomicI32.html#method.fetch_min).
-    pub fn atomic_min<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_min<T: Copy>(dst: *mut T, src: T) -> T;
     /// Minimum with the current value using a signed comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -668,7 +668,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Acquire`](../../std/sync/atomic/enum.Ordering.html#variant.Acquire)
     /// as the `order`. For example,
     /// [`AtomicI32::fetch_min`](../../std/sync/atomic/struct.AtomicI32.html#method.fetch_min).
-    pub fn atomic_min_acq<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_min_acq<T: Copy>(dst: *mut T, src: T) -> T;
     /// Minimum with the current value using a signed comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -676,7 +676,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Release`](../../std/sync/atomic/enum.Ordering.html#variant.Release)
     /// as the `order`. For example,
     /// [`AtomicI32::fetch_min`](../../std/sync/atomic/struct.AtomicI32.html#method.fetch_min).
-    pub fn atomic_min_rel<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_min_rel<T: Copy>(dst: *mut T, src: T) -> T;
     /// Minimum with the current value using a signed comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -684,7 +684,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::AcqRel`](../../std/sync/atomic/enum.Ordering.html#variant.AcqRel)
     /// as the `order`. For example,
     /// [`AtomicI32::fetch_min`](../../std/sync/atomic/struct.AtomicI32.html#method.fetch_min).
-    pub fn atomic_min_acqrel<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_min_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
     /// Minimum with the current value using a signed comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -692,7 +692,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Relaxed`](../../std/sync/atomic/enum.Ordering.html#variant.Relaxed)
     /// as the `order`. For example,
     /// [`AtomicI32::fetch_min`](../../std/sync/atomic/struct.AtomicI32.html#method.fetch_min).
-    pub fn atomic_min_relaxed<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_min_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
     /// Minimum with the current value using an unsigned comparison.
     ///
@@ -701,7 +701,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::SeqCst`](../../std/sync/atomic/enum.Ordering.html#variant.SeqCst)
     /// as the `order`. For example,
     /// [`AtomicU32::fetch_min`](../../std/sync/atomic/struct.AtomicU32.html#method.fetch_min).
-    pub fn atomic_umin<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_umin<T: Copy>(dst: *mut T, src: T) -> T;
     /// Minimum with the current value using an unsigned comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -709,7 +709,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Acquire`](../../std/sync/atomic/enum.Ordering.html#variant.Acquire)
     /// as the `order`. For example,
     /// [`AtomicU32::fetch_min`](../../std/sync/atomic/struct.AtomicU32.html#method.fetch_min).
-    pub fn atomic_umin_acq<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_umin_acq<T: Copy>(dst: *mut T, src: T) -> T;
     /// Minimum with the current value using an unsigned comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -717,7 +717,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Release`](../../std/sync/atomic/enum.Ordering.html#variant.Release)
     /// as the `order`. For example,
     /// [`AtomicU32::fetch_min`](../../std/sync/atomic/struct.AtomicU32.html#method.fetch_min).
-    pub fn atomic_umin_rel<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_umin_rel<T: Copy>(dst: *mut T, src: T) -> T;
     /// Minimum with the current value using an unsigned comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -725,7 +725,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::AcqRel`](../../std/sync/atomic/enum.Ordering.html#variant.AcqRel)
     /// as the `order`. For example,
     /// [`AtomicU32::fetch_min`](../../std/sync/atomic/struct.AtomicU32.html#method.fetch_min).
-    pub fn atomic_umin_acqrel<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_umin_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
     /// Minimum with the current value using an unsigned comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -733,7 +733,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Relaxed`](../../std/sync/atomic/enum.Ordering.html#variant.Relaxed)
     /// as the `order`. For example,
     /// [`AtomicU32::fetch_min`](../../std/sync/atomic/struct.AtomicU32.html#method.fetch_min).
-    pub fn atomic_umin_relaxed<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_umin_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
     /// Maximum with the current value using an unsigned comparison.
     ///
@@ -742,7 +742,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::SeqCst`](../../std/sync/atomic/enum.Ordering.html#variant.SeqCst)
     /// as the `order`. For example,
     /// [`AtomicU32::fetch_max`](../../std/sync/atomic/struct.AtomicU32.html#method.fetch_max).
-    pub fn atomic_umax<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_umax<T: Copy>(dst: *mut T, src: T) -> T;
     /// Maximum with the current value using an unsigned comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -750,7 +750,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Acquire`](../../std/sync/atomic/enum.Ordering.html#variant.Acquire)
     /// as the `order`. For example,
     /// [`AtomicU32::fetch_max`](../../std/sync/atomic/struct.AtomicU32.html#method.fetch_max).
-    pub fn atomic_umax_acq<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_umax_acq<T: Copy>(dst: *mut T, src: T) -> T;
     /// Maximum with the current value using an unsigned comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -758,7 +758,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Release`](../../std/sync/atomic/enum.Ordering.html#variant.Release)
     /// as the `order`. For example,
     /// [`AtomicU32::fetch_max`](../../std/sync/atomic/struct.AtomicU32.html#method.fetch_max).
-    pub fn atomic_umax_rel<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_umax_rel<T: Copy>(dst: *mut T, src: T) -> T;
     /// Maximum with the current value using an unsigned comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -766,7 +766,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::AcqRel`](../../std/sync/atomic/enum.Ordering.html#variant.AcqRel)
     /// as the `order`. For example,
     /// [`AtomicU32::fetch_max`](../../std/sync/atomic/struct.AtomicU32.html#method.fetch_max).
-    pub fn atomic_umax_acqrel<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_umax_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
     /// Maximum with the current value using an unsigned comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -774,7 +774,7 @@ extern "rust-intrinsic" {
     /// [`Ordering::Relaxed`](../../std/sync/atomic/enum.Ordering.html#variant.Relaxed)
     /// as the `order`. For example,
     /// [`AtomicU32::fetch_max`](../../std/sync/atomic/struct.AtomicU32.html#method.fetch_max).
-    pub fn atomic_umax_relaxed<T>(dst: *mut T, src: T) -> T;
+    pub fn atomic_umax_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
     /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
     /// if supported; otherwise, it is a no-op.

From ec853b6b60e9cbe7b07458f9c33f0bb3f52e0776 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= <tomasz.miasko@gmail.com>
Date: Wed, 18 Mar 2020 00:00:00 +0000
Subject: [PATCH 11/12] Add copy bound to numeric intrinsics

---
 src/libcore/intrinsics.rs | 62 +++++++++++++++++++--------------------
 1 file changed, 31 insertions(+), 31 deletions(-)

diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 47ac08e2f1095..663a89bcd32c8 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -1550,28 +1550,28 @@ extern "rust-intrinsic" {
 
     /// Float addition that allows optimizations based on algebraic rules.
     /// May assume inputs are finite.
-    pub fn fadd_fast<T>(a: T, b: T) -> T;
+    pub fn fadd_fast<T: Copy>(a: T, b: T) -> T;
 
     /// Float subtraction that allows optimizations based on algebraic rules.
     /// May assume inputs are finite.
-    pub fn fsub_fast<T>(a: T, b: T) -> T;
+    pub fn fsub_fast<T: Copy>(a: T, b: T) -> T;
 
     /// Float multiplication that allows optimizations based on algebraic rules.
     /// May assume inputs are finite.
-    pub fn fmul_fast<T>(a: T, b: T) -> T;
+    pub fn fmul_fast<T: Copy>(a: T, b: T) -> T;
 
     /// Float division that allows optimizations based on algebraic rules.
     /// May assume inputs are finite.
-    pub fn fdiv_fast<T>(a: T, b: T) -> T;
+    pub fn fdiv_fast<T: Copy>(a: T, b: T) -> T;
 
     /// Float remainder that allows optimizations based on algebraic rules.
     /// May assume inputs are finite.
-    pub fn frem_fast<T>(a: T, b: T) -> T;
+    pub fn frem_fast<T: Copy>(a: T, b: T) -> T;
 
     /// Convert with LLVM’s fptoui/fptosi, which may return undef for values out of range
     /// (<https://github.com/rust-lang/rust/issues/10184>)
     /// This is under stabilization at <https://github.com/rust-lang/rust/issues/67058>
-    pub fn float_to_int_approx_unchecked<Float, Int>(value: Float) -> Int;
+    pub fn float_to_int_approx_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
 
     /// Returns the number of bits set in an integer type `T`
     ///
@@ -1579,7 +1579,7 @@ extern "rust-intrinsic" {
     /// primitives via the `count_ones` method. For example,
     /// [`std::u32::count_ones`](../../std/primitive.u32.html#method.count_ones)
     #[rustc_const_stable(feature = "const_ctpop", since = "1.40.0")]
-    pub fn ctpop<T>(x: T) -> T;
+    pub fn ctpop<T: Copy>(x: T) -> T;
 
     /// Returns the number of leading unset bits (zeroes) in an integer type `T`.
     ///
@@ -1611,7 +1611,7 @@ extern "rust-intrinsic" {
     /// assert_eq!(num_leading, 16);
     /// ```
     #[rustc_const_stable(feature = "const_ctlz", since = "1.40.0")]
-    pub fn ctlz<T>(x: T) -> T;
+    pub fn ctlz<T: Copy>(x: T) -> T;
 
     /// Like `ctlz`, but extra-unsafe as it returns `undef` when
     /// given an `x` with value `0`.
@@ -1628,7 +1628,7 @@ extern "rust-intrinsic" {
     /// assert_eq!(num_leading, 3);
     /// ```
     #[rustc_const_unstable(feature = "constctlz", issue = "none")]
-    pub fn ctlz_nonzero<T>(x: T) -> T;
+    pub fn ctlz_nonzero<T: Copy>(x: T) -> T;
 
     /// Returns the number of trailing unset bits (zeroes) in an integer type `T`.
     ///
@@ -1660,7 +1660,7 @@ extern "rust-intrinsic" {
     /// assert_eq!(num_trailing, 16);
     /// ```
     #[rustc_const_stable(feature = "const_cttz", since = "1.40.0")]
-    pub fn cttz<T>(x: T) -> T;
+    pub fn cttz<T: Copy>(x: T) -> T;
 
     /// Like `cttz`, but extra-unsafe as it returns `undef` when
     /// given an `x` with value `0`.
@@ -1677,7 +1677,7 @@ extern "rust-intrinsic" {
     /// assert_eq!(num_trailing, 3);
     /// ```
     #[rustc_const_unstable(feature = "const_cttz", issue = "none")]
-    pub fn cttz_nonzero<T>(x: T) -> T;
+    pub fn cttz_nonzero<T: Copy>(x: T) -> T;
 
     /// Reverses the bytes in an integer type `T`.
     ///
@@ -1685,7 +1685,7 @@ extern "rust-intrinsic" {
     /// primitives via the `swap_bytes` method. For example,
     /// [`std::u32::swap_bytes`](../../std/primitive.u32.html#method.swap_bytes)
     #[rustc_const_stable(feature = "const_bswap", since = "1.40.0")]
-    pub fn bswap<T>(x: T) -> T;
+    pub fn bswap<T: Copy>(x: T) -> T;
 
     /// Reverses the bits in an integer type `T`.
     ///
@@ -1693,7 +1693,7 @@ extern "rust-intrinsic" {
     /// primitives via the `reverse_bits` method. For example,
     /// [`std::u32::reverse_bits`](../../std/primitive.u32.html#method.reverse_bits)
     #[rustc_const_stable(feature = "const_bitreverse", since = "1.40.0")]
-    pub fn bitreverse<T>(x: T) -> T;
+    pub fn bitreverse<T: Copy>(x: T) -> T;
 
     /// Performs checked integer addition.
     ///
@@ -1701,7 +1701,7 @@ extern "rust-intrinsic" {
     /// primitives via the `overflowing_add` method. For example,
     /// [`std::u32::overflowing_add`](../../std/primitive.u32.html#method.overflowing_add)
     #[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")]
-    pub fn add_with_overflow<T>(x: T, y: T) -> (T, bool);
+    pub fn add_with_overflow<T: Copy>(x: T, y: T) -> (T, bool);
 
     /// Performs checked integer subtraction
     ///
@@ -1709,7 +1709,7 @@ extern "rust-intrinsic" {
     /// primitives via the `overflowing_sub` method. For example,
     /// [`std::u32::overflowing_sub`](../../std/primitive.u32.html#method.overflowing_sub)
     #[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")]
-    pub fn sub_with_overflow<T>(x: T, y: T) -> (T, bool);
+    pub fn sub_with_overflow<T: Copy>(x: T, y: T) -> (T, bool);
 
     /// Performs checked integer multiplication
     ///
@@ -1717,11 +1717,11 @@ extern "rust-intrinsic" {
     /// primitives via the `overflowing_mul` method. For example,
     /// [`std::u32::overflowing_mul`](../../std/primitive.u32.html#method.overflowing_mul)
     #[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")]
-    pub fn mul_with_overflow<T>(x: T, y: T) -> (T, bool);
+    pub fn mul_with_overflow<T: Copy>(x: T, y: T) -> (T, bool);
 
     /// Performs an exact division, resulting in undefined behavior where
     /// `x % y != 0` or `y == 0` or `x == T::min_value() && y == -1`
-    pub fn exact_div<T>(x: T, y: T) -> T;
+    pub fn exact_div<T: Copy>(x: T, y: T) -> T;
 
     /// Performs an unchecked division, resulting in undefined behavior
     /// where y = 0 or x = `T::min_value()` and y = -1
@@ -1730,7 +1730,7 @@ extern "rust-intrinsic" {
     /// primitives via the `checked_div` method. For example,
     /// [`std::u32::checked_div`](../../std/primitive.u32.html#method.checked_div)
     #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
-    pub fn unchecked_div<T>(x: T, y: T) -> T;
+    pub fn unchecked_div<T: Copy>(x: T, y: T) -> T;
     /// Returns the remainder of an unchecked division, resulting in
     /// undefined behavior where y = 0 or x = `T::min_value()` and y = -1
     ///
@@ -1738,7 +1738,7 @@ extern "rust-intrinsic" {
     /// primitives via the `checked_rem` method. For example,
     /// [`std::u32::checked_rem`](../../std/primitive.u32.html#method.checked_rem)
     #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
-    pub fn unchecked_rem<T>(x: T, y: T) -> T;
+    pub fn unchecked_rem<T: Copy>(x: T, y: T) -> T;
 
     /// Performs an unchecked left shift, resulting in undefined behavior when
     /// y < 0 or y >= N, where N is the width of T in bits.
@@ -1747,7 +1747,7 @@ extern "rust-intrinsic" {
     /// primitives via the `checked_shl` method. For example,
     /// [`std::u32::checked_shl`](../../std/primitive.u32.html#method.checked_shl)
     #[rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0")]
-    pub fn unchecked_shl<T>(x: T, y: T) -> T;
+    pub fn unchecked_shl<T: Copy>(x: T, y: T) -> T;
     /// Performs an unchecked right shift, resulting in undefined behavior when
     /// y < 0 or y >= N, where N is the width of T in bits.
     ///
@@ -1755,22 +1755,22 @@ extern "rust-intrinsic" {
     /// primitives via the `checked_shr` method. For example,
     /// [`std::u32::checked_shr`](../../std/primitive.u32.html#method.checked_shr)
     #[rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0")]
-    pub fn unchecked_shr<T>(x: T, y: T) -> T;
+    pub fn unchecked_shr<T: Copy>(x: T, y: T) -> T;
 
     /// Returns the result of an unchecked addition, resulting in
     /// undefined behavior when `x + y > T::max_value()` or `x + y < T::min_value()`.
     #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
-    pub fn unchecked_add<T>(x: T, y: T) -> T;
+    pub fn unchecked_add<T: Copy>(x: T, y: T) -> T;
 
     /// Returns the result of an unchecked subtraction, resulting in
     /// undefined behavior when `x - y > T::max_value()` or `x - y < T::min_value()`.
     #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
-    pub fn unchecked_sub<T>(x: T, y: T) -> T;
+    pub fn unchecked_sub<T: Copy>(x: T, y: T) -> T;
 
     /// Returns the result of an unchecked multiplication, resulting in
     /// undefined behavior when `x * y > T::max_value()` or `x * y < T::min_value()`.
     #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
-    pub fn unchecked_mul<T>(x: T, y: T) -> T;
+    pub fn unchecked_mul<T: Copy>(x: T, y: T) -> T;
 
     /// Performs rotate left.
     ///
@@ -1778,7 +1778,7 @@ extern "rust-intrinsic" {
     /// primitives via the `rotate_left` method. For example,
     /// [`std::u32::rotate_left`](../../std/primitive.u32.html#method.rotate_left)
     #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")]
-    pub fn rotate_left<T>(x: T, y: T) -> T;
+    pub fn rotate_left<T: Copy>(x: T, y: T) -> T;
 
     /// Performs rotate right.
     ///
@@ -1786,7 +1786,7 @@ extern "rust-intrinsic" {
     /// primitives via the `rotate_right` method. For example,
     /// [`std::u32::rotate_right`](../../std/primitive.u32.html#method.rotate_right)
     #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")]
-    pub fn rotate_right<T>(x: T, y: T) -> T;
+    pub fn rotate_right<T: Copy>(x: T, y: T) -> T;
 
     /// Returns (a + b) mod 2<sup>N</sup>, where N is the width of T in bits.
     ///
@@ -1794,21 +1794,21 @@ extern "rust-intrinsic" {
     /// primitives via the `checked_add` method. For example,
     /// [`std::u32::checked_add`](../../std/primitive.u32.html#method.checked_add)
     #[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")]
-    pub fn wrapping_add<T>(a: T, b: T) -> T;
+    pub fn wrapping_add<T: Copy>(a: T, b: T) -> T;
     /// Returns (a - b) mod 2<sup>N</sup>, where N is the width of T in bits.
     ///
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `checked_sub` method. For example,
     /// [`std::u32::checked_sub`](../../std/primitive.u32.html#method.checked_sub)
     #[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")]
-    pub fn wrapping_sub<T>(a: T, b: T) -> T;
+    pub fn wrapping_sub<T: Copy>(a: T, b: T) -> T;
     /// Returns (a * b) mod 2<sup>N</sup>, where N is the width of T in bits.
     ///
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `checked_mul` method. For example,
     /// [`std::u32::checked_mul`](../../std/primitive.u32.html#method.checked_mul)
     #[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")]
-    pub fn wrapping_mul<T>(a: T, b: T) -> T;
+    pub fn wrapping_mul<T: Copy>(a: T, b: T) -> T;
 
     /// Computes `a + b`, while saturating at numeric bounds.
     ///
@@ -1816,14 +1816,14 @@ extern "rust-intrinsic" {
     /// primitives via the `saturating_add` method. For example,
     /// [`std::u32::saturating_add`](../../std/primitive.u32.html#method.saturating_add)
     #[rustc_const_stable(feature = "const_int_saturating", since = "1.40.0")]
-    pub fn saturating_add<T>(a: T, b: T) -> T;
+    pub fn saturating_add<T: Copy>(a: T, b: T) -> T;
     /// Computes `a - b`, while saturating at numeric bounds.
     ///
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `saturating_sub` method. For example,
     /// [`std::u32::saturating_sub`](../../std/primitive.u32.html#method.saturating_sub)
     #[rustc_const_stable(feature = "const_int_saturating", since = "1.40.0")]
-    pub fn saturating_sub<T>(a: T, b: T) -> T;
+    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.

From e92d740b3586de0d0b476257b3539847f2db21e3 Mon Sep 17 00:00:00 2001
From: Stein Somers <git@steinsomers.be>
Date: Sat, 8 Feb 2020 11:52:14 +0100
Subject: [PATCH 12/12] BTreeMap testing: introduce symbolic constants and
 refer to height consistently.

---
 src/liballoc/tests/btree/map.rs | 90 ++++++++++++++++++---------------
 1 file changed, 49 insertions(+), 41 deletions(-)

diff --git a/src/liballoc/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs
index 3a3462d546f7a..535b6a9c31451 100644
--- a/src/liballoc/tests/btree/map.rs
+++ b/src/liballoc/tests/btree/map.rs
@@ -7,17 +7,31 @@ use std::ops::Bound::{self, Excluded, Included, Unbounded};
 use std::ops::RangeBounds;
 use std::panic::catch_unwind;
 use std::rc::Rc;
-use std::sync::atomic::{AtomicU32, Ordering};
+use std::sync::atomic::{AtomicUsize, Ordering};
 
 use super::DeterministicRng;
 
+// Value of node::CAPACITY, thus capacity of a tree with a single level,
+// i.e. a tree who's root is a leaf node at height 0.
+const NODE_CAPACITY: usize = 11;
+
+// Minimum number of elements to insert in order to guarantee a tree with 2 levels,
+// i.e. a tree who's root is an internal node at height 1, with edges to leaf nodes.
+// It's not the minimum size: removing an element from such a tree does not always reduce height.
+const MIN_INSERTS_HEIGHT_1: usize = NODE_CAPACITY + 1;
+
+// Minimum number of elements to insert in order to guarantee a tree with 3 levels,
+// i.e. a tree who's root is an internal node at height 2, with edges to more internal nodes.
+// It's not the minimum size: removing an element from such a tree does not always reduce height.
+const MIN_INSERTS_HEIGHT_2: usize = NODE_CAPACITY + (NODE_CAPACITY + 1) * NODE_CAPACITY + 1;
+
 #[test]
 fn test_basic_large() {
     let mut map = BTreeMap::new();
     #[cfg(not(miri))] // Miri is too slow
     let size = 10000;
     #[cfg(miri)]
-    let size = 144; // to obtain height 3 tree (having edges to both kinds of nodes)
+    let size = MIN_INSERTS_HEIGHT_2;
     assert_eq!(map.len(), 0);
 
     for i in 0..size {
@@ -237,30 +251,26 @@ impl TryFrom<usize> for Align32 {
 
 #[test]
 fn test_iter_mut_mutation() {
-    // Check many alignments because various fields precede array in NodeHeader.
-    // Check with size 0 which should not iterate at all.
-    // Check with size 1 for a tree with one kind of node (root = leaf).
-    // Check with size 12 for a tree with two kinds of nodes (root and leaves).
-    // Check with size 144 for a tree with all kinds of nodes (root, internals and leaves).
+    // Check many alignments and trees with roots at various heights.
     do_test_iter_mut_mutation::<u8>(0);
     do_test_iter_mut_mutation::<u8>(1);
-    do_test_iter_mut_mutation::<u8>(12);
-    do_test_iter_mut_mutation::<u8>(127); // not enough unique values to test 144
+    do_test_iter_mut_mutation::<u8>(MIN_INSERTS_HEIGHT_1);
+    do_test_iter_mut_mutation::<u8>(127); // not enough unique values to test MIN_INSERTS_HEIGHT_2
     do_test_iter_mut_mutation::<u16>(1);
-    do_test_iter_mut_mutation::<u16>(12);
-    do_test_iter_mut_mutation::<u16>(144);
+    do_test_iter_mut_mutation::<u16>(MIN_INSERTS_HEIGHT_1);
+    do_test_iter_mut_mutation::<u16>(MIN_INSERTS_HEIGHT_2);
     do_test_iter_mut_mutation::<u32>(1);
-    do_test_iter_mut_mutation::<u32>(12);
-    do_test_iter_mut_mutation::<u32>(144);
+    do_test_iter_mut_mutation::<u32>(MIN_INSERTS_HEIGHT_1);
+    do_test_iter_mut_mutation::<u32>(MIN_INSERTS_HEIGHT_2);
     do_test_iter_mut_mutation::<u64>(1);
-    do_test_iter_mut_mutation::<u64>(12);
-    do_test_iter_mut_mutation::<u64>(144);
+    do_test_iter_mut_mutation::<u64>(MIN_INSERTS_HEIGHT_1);
+    do_test_iter_mut_mutation::<u64>(MIN_INSERTS_HEIGHT_2);
     do_test_iter_mut_mutation::<u128>(1);
-    do_test_iter_mut_mutation::<u128>(12);
-    do_test_iter_mut_mutation::<u128>(144);
+    do_test_iter_mut_mutation::<u128>(MIN_INSERTS_HEIGHT_1);
+    do_test_iter_mut_mutation::<u128>(MIN_INSERTS_HEIGHT_2);
     do_test_iter_mut_mutation::<Align32>(1);
-    do_test_iter_mut_mutation::<Align32>(12);
-    do_test_iter_mut_mutation::<Align32>(144);
+    do_test_iter_mut_mutation::<Align32>(MIN_INSERTS_HEIGHT_1);
+    do_test_iter_mut_mutation::<Align32>(MIN_INSERTS_HEIGHT_2);
 }
 
 #[test]
@@ -376,12 +386,11 @@ fn test_range_small() {
 }
 
 #[test]
-fn test_range_height_2() {
-    // Assuming that node.CAPACITY is 11, having 12 pairs implies a height 2 tree
-    // with 2 leaves. Depending on details we don't want or need to rely upon,
-    // the single key at the root will be 6 or 7.
+fn test_range_height_1() {
+    // Tests tree with a root and 2 leaves. Depending on details we don't want or need
+    // to rely upon, the single key at the root will be 6 or 7.
 
-    let map: BTreeMap<_, _> = (1..=12).map(|i| (i, i)).collect();
+    let map: BTreeMap<_, _> = (1..=MIN_INSERTS_HEIGHT_1 as i32).map(|i| (i, i)).collect();
     for &root in &[6, 7] {
         assert_eq!(range_keys(&map, (Excluded(root), Excluded(root + 1))), vec![]);
         assert_eq!(range_keys(&map, (Excluded(root), Included(root + 1))), vec![root + 1]);
@@ -519,7 +528,7 @@ fn test_range_1000() {
     #[cfg(not(miri))] // Miri is too slow
     let size = 1000;
     #[cfg(miri)]
-    let size = 144; // to obtain height 3 tree (having edges to both kinds of nodes)
+    let size = MIN_INSERTS_HEIGHT_2;
     let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
 
     fn test(map: &BTreeMap<u32, u32>, size: u32, min: Bound<&u32>, max: Bound<&u32>) {
@@ -755,7 +764,7 @@ fn test_bad_zst() {
 #[test]
 fn test_clone() {
     let mut map = BTreeMap::new();
-    let size = 12; // to obtain height 2 tree (having edges to leaf nodes)
+    let size = MIN_INSERTS_HEIGHT_1;
     assert_eq!(map.len(), 0);
 
     for i in 0..size {
@@ -783,20 +792,19 @@ fn test_clone() {
         assert_eq!(map, map.clone());
     }
 
-    // Full 2-level and minimal 3-level tree (sizes 143, 144 -- the only ones we clone for).
-    for i in 1..=144 {
-        assert_eq!(map.insert(i, i), None);
-        assert_eq!(map.len(), i);
-        if i >= 143 {
-            assert_eq!(map, map.clone());
-        }
-    }
+    // Test a tree with 2 chock-full levels and a tree with 3 levels.
+    map = (1..MIN_INSERTS_HEIGHT_2).map(|i| (i, i)).collect();
+    assert_eq!(map.len(), MIN_INSERTS_HEIGHT_2 - 1);
+    assert_eq!(map, map.clone());
+    map.insert(0, 0);
+    assert_eq!(map.len(), MIN_INSERTS_HEIGHT_2);
+    assert_eq!(map, map.clone());
 }
 
 #[test]
 fn test_clone_from() {
     let mut map1 = BTreeMap::new();
-    let max_size = 12; // to obtain height 2 tree (having edges to leaf nodes)
+    let max_size = MIN_INSERTS_HEIGHT_1;
 
     // Range to max_size inclusive, because i is the size of map1 being tested.
     for i in 0..=max_size {
@@ -1014,8 +1022,8 @@ fn test_split_off_large_random_sorted() {
 }
 
 #[test]
-fn test_into_iter_drop_leak_1() {
-    static DROPS: AtomicU32 = AtomicU32::new(0);
+fn test_into_iter_drop_leak_height_0() {
+    static DROPS: AtomicUsize = AtomicUsize::new(0);
 
     struct D;
 
@@ -1040,10 +1048,10 @@ fn test_into_iter_drop_leak_1() {
 }
 
 #[test]
-fn test_into_iter_drop_leak_2() {
-    let size = 12; // to obtain tree with 2 levels (having edges to leaf nodes)
-    static DROPS: AtomicU32 = AtomicU32::new(0);
-    static PANIC_POINT: AtomicU32 = AtomicU32::new(0);
+fn test_into_iter_drop_leak_height_1() {
+    let size = MIN_INSERTS_HEIGHT_1;
+    static DROPS: AtomicUsize = AtomicUsize::new(0);
+    static PANIC_POINT: AtomicUsize = AtomicUsize::new(0);
 
     struct D;
     impl Drop for D {