about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-08-02 01:40:56 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-08-02 01:59:01 +0300
commit3d0d6ee271a34d2329235b9a04cf4a421d9026cd (patch)
treebdd574c1b42fe28031d69a18d7f7694ce8742021
parent310b9fc76002066feb89dcfbf8e88b34fe5f4ad3 (diff)
downloadrust-3d0d6ee271a34d2329235b9a04cf4a421d9026cd.tar.gz
rust-3d0d6ee271a34d2329235b9a04cf4a421d9026cd.zip
liballoc: Unconfigure tests during normal build
Remove additional libcore-like restrictions from liballoc, turns out the testing works ok if the tests are a part of liballoc itself.
-rw-r--r--src/liballoc/alloc.rs36
-rw-r--r--src/liballoc/alloc/tests.rs30
-rw-r--r--src/liballoc/collections/linked_list.rs273
-rw-r--r--src/liballoc/collections/linked_list/tests.rs265
-rw-r--r--src/liballoc/collections/vec_deque.rs389
-rw-r--r--src/liballoc/collections/vec_deque/tests.rs379
-rw-r--r--src/liballoc/raw_vec.rs82
-rw-r--r--src/liballoc/raw_vec/tests.rs73
-rw-r--r--src/liballoc/rc.rs433
-rw-r--r--src/liballoc/rc/tests.rs427
-rw-r--r--src/liballoc/sync.rs486
-rw-r--r--src/liballoc/sync/tests.rs480
-rw-r--r--src/tools/tidy/src/unit_tests.rs36
13 files changed, 1682 insertions, 1707 deletions
diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs
index cef2b5eea34..dc7fd1adc29 100644
--- a/src/liballoc/alloc.rs
+++ b/src/liballoc/alloc.rs
@@ -10,6 +10,9 @@ use core::usize;
 #[doc(inline)]
 pub use core::alloc::*;
 
+#[cfg(test)]
+mod tests;
+
 extern "Rust" {
     // These are the magic symbols to call the global allocator.  rustc generates
     // them from the `#[global_allocator]` attribute if there is one, or uses the
@@ -244,36 +247,3 @@ pub fn handle_alloc_error(layout: Layout) -> ! {
     }
     unsafe { oom_impl(layout) }
 }
-
-#[cfg(test)]
-mod tests {
-    extern crate test;
-    use test::Bencher;
-    use crate::boxed::Box;
-    use crate::alloc::{Global, Alloc, Layout, handle_alloc_error};
-
-    #[test]
-    fn allocate_zeroed() {
-        unsafe {
-            let layout = Layout::from_size_align(1024, 1).unwrap();
-            let ptr = Global.alloc_zeroed(layout.clone())
-                .unwrap_or_else(|_| handle_alloc_error(layout));
-
-            let mut i = ptr.cast::<u8>().as_ptr();
-            let end = i.add(layout.size());
-            while i < end {
-                assert_eq!(*i, 0);
-                i = i.offset(1);
-            }
-            Global.dealloc(ptr, layout);
-        }
-    }
-
-    #[bench]
-    #[cfg(not(miri))] // Miri does not support benchmarks
-    fn alloc_owned_small(b: &mut Bencher) {
-        b.iter(|| {
-            let _: Box<_> = box 10;
-        })
-    }
-}
diff --git a/src/liballoc/alloc/tests.rs b/src/liballoc/alloc/tests.rs
new file mode 100644
index 00000000000..c69f4e49ee1
--- /dev/null
+++ b/src/liballoc/alloc/tests.rs
@@ -0,0 +1,30 @@
+use super::*;
+
+extern crate test;
+use test::Bencher;
+use crate::boxed::Box;
+
+#[test]
+fn allocate_zeroed() {
+    unsafe {
+        let layout = Layout::from_size_align(1024, 1).unwrap();
+        let ptr = Global.alloc_zeroed(layout.clone())
+            .unwrap_or_else(|_| handle_alloc_error(layout));
+
+        let mut i = ptr.cast::<u8>().as_ptr();
+        let end = i.add(layout.size());
+        while i < end {
+            assert_eq!(*i, 0);
+            i = i.offset(1);
+        }
+        Global.dealloc(ptr, layout);
+    }
+}
+
+#[bench]
+#[cfg(not(miri))] // Miri does not support benchmarks
+fn alloc_owned_small(b: &mut Bencher) {
+    b.iter(|| {
+        let _: Box<_> = box 10;
+    })
+}
diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs
index bbb96725ea0..a14a3fe9994 100644
--- a/src/liballoc/collections/linked_list.rs
+++ b/src/liballoc/collections/linked_list.rs
@@ -23,6 +23,9 @@ use core::ptr::NonNull;
 use crate::boxed::Box;
 use super::SpecExtend;
 
+#[cfg(test)]
+mod tests;
+
 /// A doubly-linked list with owned nodes.
 ///
 /// The `LinkedList` allows pushing and popping elements at either end
@@ -1244,273 +1247,3 @@ unsafe impl<T: Send> Send for IterMut<'_, T> {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 unsafe impl<T: Sync> Sync for IterMut<'_, T> {}
-
-#[cfg(test)]
-mod tests {
-    use std::thread;
-    use std::vec::Vec;
-
-    use rand::{thread_rng, RngCore};
-
-    use super::{LinkedList, Node};
-
-    #[cfg(test)]
-    fn list_from<T: Clone>(v: &[T]) -> LinkedList<T> {
-        v.iter().cloned().collect()
-    }
-
-    pub fn check_links<T>(list: &LinkedList<T>) {
-        unsafe {
-            let mut len = 0;
-            let mut last_ptr: Option<&Node<T>> = None;
-            let mut node_ptr: &Node<T>;
-            match list.head {
-                None => {
-                    // tail node should also be None.
-                    assert!(list.tail.is_none());
-                    assert_eq!(0, list.len);
-                    return;
-                }
-                Some(node) => node_ptr = &*node.as_ptr(),
-            }
-            loop {
-                match (last_ptr, node_ptr.prev) {
-                    (None, None) => {}
-                    (None, _) => panic!("prev link for head"),
-                    (Some(p), Some(pptr)) => {
-                        assert_eq!(p as *const Node<T>, pptr.as_ptr() as *const Node<T>);
-                    }
-                    _ => panic!("prev link is none, not good"),
-                }
-                match node_ptr.next {
-                    Some(next) => {
-                        last_ptr = Some(node_ptr);
-                        node_ptr = &*next.as_ptr();
-                        len += 1;
-                    }
-                    None => {
-                        len += 1;
-                        break;
-                    }
-                }
-            }
-
-            // verify that the tail node points to the last node.
-            let tail = list.tail.as_ref().expect("some tail node").as_ref();
-            assert_eq!(tail as *const Node<T>, node_ptr as *const Node<T>);
-            // check that len matches interior links.
-            assert_eq!(len, list.len);
-        }
-    }
-
-    #[test]
-    fn test_append() {
-        // Empty to empty
-        {
-            let mut m = LinkedList::<i32>::new();
-            let mut n = LinkedList::new();
-            m.append(&mut n);
-            check_links(&m);
-            assert_eq!(m.len(), 0);
-            assert_eq!(n.len(), 0);
-        }
-        // Non-empty to empty
-        {
-            let mut m = LinkedList::new();
-            let mut n = LinkedList::new();
-            n.push_back(2);
-            m.append(&mut n);
-            check_links(&m);
-            assert_eq!(m.len(), 1);
-            assert_eq!(m.pop_back(), Some(2));
-            assert_eq!(n.len(), 0);
-            check_links(&m);
-        }
-        // Empty to non-empty
-        {
-            let mut m = LinkedList::new();
-            let mut n = LinkedList::new();
-            m.push_back(2);
-            m.append(&mut n);
-            check_links(&m);
-            assert_eq!(m.len(), 1);
-            assert_eq!(m.pop_back(), Some(2));
-            check_links(&m);
-        }
-
-        // Non-empty to non-empty
-        let v = vec![1, 2, 3, 4, 5];
-        let u = vec![9, 8, 1, 2, 3, 4, 5];
-        let mut m = list_from(&v);
-        let mut n = list_from(&u);
-        m.append(&mut n);
-        check_links(&m);
-        let mut sum = v;
-        sum.extend_from_slice(&u);
-        assert_eq!(sum.len(), m.len());
-        for elt in sum {
-            assert_eq!(m.pop_front(), Some(elt))
-        }
-        assert_eq!(n.len(), 0);
-        // let's make sure it's working properly, since we
-        // did some direct changes to private members
-        n.push_back(3);
-        assert_eq!(n.len(), 1);
-        assert_eq!(n.pop_front(), Some(3));
-        check_links(&n);
-    }
-
-    #[test]
-    fn test_insert_prev() {
-        let mut m = list_from(&[0, 2, 4, 6, 8]);
-        let len = m.len();
-        {
-            let mut it = m.iter_mut();
-            it.insert_next(-2);
-            loop {
-                match it.next() {
-                    None => break,
-                    Some(elt) => {
-                        it.insert_next(*elt + 1);
-                        match it.peek_next() {
-                            Some(x) => assert_eq!(*x, *elt + 2),
-                            None => assert_eq!(8, *elt),
-                        }
-                    }
-                }
-            }
-            it.insert_next(0);
-            it.insert_next(1);
-        }
-        check_links(&m);
-        assert_eq!(m.len(), 3 + len * 2);
-        assert_eq!(m.into_iter().collect::<Vec<_>>(),
-                   [-2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1]);
-    }
-
-    #[test]
-    #[cfg_attr(target_os = "emscripten", ignore)]
-    #[cfg(not(miri))] // Miri does not support threads
-    fn test_send() {
-        let n = list_from(&[1, 2, 3]);
-        thread::spawn(move || {
-                check_links(&n);
-                let a: &[_] = &[&1, &2, &3];
-                assert_eq!(a, &*n.iter().collect::<Vec<_>>());
-            })
-            .join()
-            .ok()
-            .unwrap();
-    }
-
-    #[test]
-    fn test_fuzz() {
-        for _ in 0..25 {
-            fuzz_test(3);
-            fuzz_test(16);
-            #[cfg(not(miri))] // Miri is too slow
-            fuzz_test(189);
-        }
-    }
-
-    #[test]
-    fn test_26021() {
-        // There was a bug in split_off that failed to null out the RHS's head's prev ptr.
-        // This caused the RHS's dtor to walk up into the LHS at drop and delete all of
-        // its nodes.
-        //
-        // https://github.com/rust-lang/rust/issues/26021
-        let mut v1 = LinkedList::new();
-        v1.push_front(1);
-        v1.push_front(1);
-        v1.push_front(1);
-        v1.push_front(1);
-        let _ = v1.split_off(3); // Dropping this now should not cause laundry consumption
-        assert_eq!(v1.len(), 3);
-
-        assert_eq!(v1.iter().len(), 3);
-        assert_eq!(v1.iter().collect::<Vec<_>>().len(), 3);
-    }
-
-    #[test]
-    fn test_split_off() {
-        let mut v1 = LinkedList::new();
-        v1.push_front(1);
-        v1.push_front(1);
-        v1.push_front(1);
-        v1.push_front(1);
-
-        // test all splits
-        for ix in 0..1 + v1.len() {
-            let mut a = v1.clone();
-            let b = a.split_off(ix);
-            check_links(&a);
-            check_links(&b);
-            a.extend(b);
-            assert_eq!(v1, a);
-        }
-    }
-
-    #[cfg(test)]
-    fn fuzz_test(sz: i32) {
-        let mut m: LinkedList<_> = LinkedList::new();
-        let mut v = vec![];
-        for i in 0..sz {
-            check_links(&m);
-            let r: u8 = thread_rng().next_u32() as u8;
-            match r % 6 {
-                0 => {
-                    m.pop_back();
-                    v.pop();
-                }
-                1 => {
-                    if !v.is_empty() {
-                        m.pop_front();
-                        v.remove(0);
-                    }
-                }
-                2 | 4 => {
-                    m.push_front(-i);
-                    v.insert(0, -i);
-                }
-                3 | 5 | _ => {
-                    m.push_back(i);
-                    v.push(i);
-                }
-            }
-        }
-
-        check_links(&m);
-
-        let mut i = 0;
-        for (a, &b) in m.into_iter().zip(&v) {
-            i += 1;
-            assert_eq!(a, b);
-        }
-        assert_eq!(i, v.len());
-    }
-
-    #[test]
-    fn drain_filter_test() {
-        let mut m: LinkedList<u32> = LinkedList::new();
-        m.extend(&[1, 2, 3, 4, 5, 6]);
-        let deleted = m.drain_filter(|v| *v < 4).collect::<Vec<_>>();
-
-        check_links(&m);
-
-        assert_eq!(deleted, &[1, 2, 3]);
-        assert_eq!(m.into_iter().collect::<Vec<_>>(), &[4, 5, 6]);
-    }
-
-    #[test]
-    fn drain_to_empty_test() {
-        let mut m: LinkedList<u32> = LinkedList::new();
-        m.extend(&[1, 2, 3, 4, 5, 6]);
-        let deleted = m.drain_filter(|_| true).collect::<Vec<_>>();
-
-        check_links(&m);
-
-        assert_eq!(deleted, &[1, 2, 3, 4, 5, 6]);
-        assert_eq!(m.into_iter().collect::<Vec<_>>(), &[]);
-    }
-}
diff --git a/src/liballoc/collections/linked_list/tests.rs b/src/liballoc/collections/linked_list/tests.rs
new file mode 100644
index 00000000000..953b0d4eb28
--- /dev/null
+++ b/src/liballoc/collections/linked_list/tests.rs
@@ -0,0 +1,265 @@
+use super::*;
+
+use std::thread;
+use std::vec::Vec;
+
+use rand::{thread_rng, RngCore};
+
+fn list_from<T: Clone>(v: &[T]) -> LinkedList<T> {
+    v.iter().cloned().collect()
+}
+
+pub fn check_links<T>(list: &LinkedList<T>) {
+    unsafe {
+        let mut len = 0;
+        let mut last_ptr: Option<&Node<T>> = None;
+        let mut node_ptr: &Node<T>;
+        match list.head {
+            None => {
+                // tail node should also be None.
+                assert!(list.tail.is_none());
+                assert_eq!(0, list.len);
+                return;
+            }
+            Some(node) => node_ptr = &*node.as_ptr(),
+        }
+        loop {
+            match (last_ptr, node_ptr.prev) {
+                (None, None) => {}
+                (None, _) => panic!("prev link for head"),
+                (Some(p), Some(pptr)) => {
+                    assert_eq!(p as *const Node<T>, pptr.as_ptr() as *const Node<T>);
+                }
+                _ => panic!("prev link is none, not good"),
+            }
+            match node_ptr.next {
+                Some(next) => {
+                    last_ptr = Some(node_ptr);
+                    node_ptr = &*next.as_ptr();
+                    len += 1;
+                }
+                None => {
+                    len += 1;
+                    break;
+                }
+            }
+        }
+
+        // verify that the tail node points to the last node.
+        let tail = list.tail.as_ref().expect("some tail node").as_ref();
+        assert_eq!(tail as *const Node<T>, node_ptr as *const Node<T>);
+        // check that len matches interior links.
+        assert_eq!(len, list.len);
+    }
+}
+
+#[test]
+fn test_append() {
+    // Empty to empty
+    {
+        let mut m = LinkedList::<i32>::new();
+        let mut n = LinkedList::new();
+        m.append(&mut n);
+        check_links(&m);
+        assert_eq!(m.len(), 0);
+        assert_eq!(n.len(), 0);
+    }
+    // Non-empty to empty
+    {
+        let mut m = LinkedList::new();
+        let mut n = LinkedList::new();
+        n.push_back(2);
+        m.append(&mut n);
+        check_links(&m);
+        assert_eq!(m.len(), 1);
+        assert_eq!(m.pop_back(), Some(2));
+        assert_eq!(n.len(), 0);
+        check_links(&m);
+    }
+    // Empty to non-empty
+    {
+        let mut m = LinkedList::new();
+        let mut n = LinkedList::new();
+        m.push_back(2);
+        m.append(&mut n);
+        check_links(&m);
+        assert_eq!(m.len(), 1);
+        assert_eq!(m.pop_back(), Some(2));
+        check_links(&m);
+    }
+
+    // Non-empty to non-empty
+    let v = vec![1, 2, 3, 4, 5];
+    let u = vec![9, 8, 1, 2, 3, 4, 5];
+    let mut m = list_from(&v);
+    let mut n = list_from(&u);
+    m.append(&mut n);
+    check_links(&m);
+    let mut sum = v;
+    sum.extend_from_slice(&u);
+    assert_eq!(sum.len(), m.len());
+    for elt in sum {
+        assert_eq!(m.pop_front(), Some(elt))
+    }
+    assert_eq!(n.len(), 0);
+    // let's make sure it's working properly, since we
+    // did some direct changes to private members
+    n.push_back(3);
+    assert_eq!(n.len(), 1);
+    assert_eq!(n.pop_front(), Some(3));
+    check_links(&n);
+}
+
+#[test]
+fn test_insert_prev() {
+    let mut m = list_from(&[0, 2, 4, 6, 8]);
+    let len = m.len();
+    {
+        let mut it = m.iter_mut();
+        it.insert_next(-2);
+        loop {
+            match it.next() {
+                None => break,
+                Some(elt) => {
+                    it.insert_next(*elt + 1);
+                    match it.peek_next() {
+                        Some(x) => assert_eq!(*x, *elt + 2),
+                        None => assert_eq!(8, *elt),
+                    }
+                }
+            }
+        }
+        it.insert_next(0);
+        it.insert_next(1);
+    }
+    check_links(&m);
+    assert_eq!(m.len(), 3 + len * 2);
+    assert_eq!(m.into_iter().collect::<Vec<_>>(),
+                [-2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1]);
+}
+
+#[test]
+#[cfg_attr(target_os = "emscripten", ignore)]
+#[cfg(not(miri))] // Miri does not support threads
+fn test_send() {
+    let n = list_from(&[1, 2, 3]);
+    thread::spawn(move || {
+            check_links(&n);
+            let a: &[_] = &[&1, &2, &3];
+            assert_eq!(a, &*n.iter().collect::<Vec<_>>());
+        })
+        .join()
+        .ok()
+        .unwrap();
+}
+
+#[test]
+fn test_fuzz() {
+    for _ in 0..25 {
+        fuzz_test(3);
+        fuzz_test(16);
+        #[cfg(not(miri))] // Miri is too slow
+        fuzz_test(189);
+    }
+}
+
+#[test]
+fn test_26021() {
+    // There was a bug in split_off that failed to null out the RHS's head's prev ptr.
+    // This caused the RHS's dtor to walk up into the LHS at drop and delete all of
+    // its nodes.
+    //
+    // https://github.com/rust-lang/rust/issues/26021
+    let mut v1 = LinkedList::new();
+    v1.push_front(1);
+    v1.push_front(1);
+    v1.push_front(1);
+    v1.push_front(1);
+    let _ = v1.split_off(3); // Dropping this now should not cause laundry consumption
+    assert_eq!(v1.len(), 3);
+
+    assert_eq!(v1.iter().len(), 3);
+    assert_eq!(v1.iter().collect::<Vec<_>>().len(), 3);
+}
+
+#[test]
+fn test_split_off() {
+    let mut v1 = LinkedList::new();
+    v1.push_front(1);
+    v1.push_front(1);
+    v1.push_front(1);
+    v1.push_front(1);
+
+    // test all splits
+    for ix in 0..1 + v1.len() {
+        let mut a = v1.clone();
+        let b = a.split_off(ix);
+        check_links(&a);
+        check_links(&b);
+        a.extend(b);
+        assert_eq!(v1, a);
+    }
+}
+
+#[cfg(test)]
+fn fuzz_test(sz: i32) {
+    let mut m: LinkedList<_> = LinkedList::new();
+    let mut v = vec![];
+    for i in 0..sz {
+        check_links(&m);
+        let r: u8 = thread_rng().next_u32() as u8;
+        match r % 6 {
+            0 => {
+                m.pop_back();
+                v.pop();
+            }
+            1 => {
+                if !v.is_empty() {
+                    m.pop_front();
+                    v.remove(0);
+                }
+            }
+            2 | 4 => {
+                m.push_front(-i);
+                v.insert(0, -i);
+            }
+            3 | 5 | _ => {
+                m.push_back(i);
+                v.push(i);
+            }
+        }
+    }
+
+    check_links(&m);
+
+    let mut i = 0;
+    for (a, &b) in m.into_iter().zip(&v) {
+        i += 1;
+        assert_eq!(a, b);
+    }
+    assert_eq!(i, v.len());
+}
+
+#[test]
+fn drain_filter_test() {
+    let mut m: LinkedList<u32> = LinkedList::new();
+    m.extend(&[1, 2, 3, 4, 5, 6]);
+    let deleted = m.drain_filter(|v| *v < 4).collect::<Vec<_>>();
+
+    check_links(&m);
+
+    assert_eq!(deleted, &[1, 2, 3]);
+    assert_eq!(m.into_iter().collect::<Vec<_>>(), &[4, 5, 6]);
+}
+
+#[test]
+fn drain_to_empty_test() {
+    let mut m: LinkedList<u32> = LinkedList::new();
+    m.extend(&[1, 2, 3, 4, 5, 6]);
+    let deleted = m.drain_filter(|_| true).collect::<Vec<_>>();
+
+    check_links(&m);
+
+    assert_eq!(deleted, &[1, 2, 3, 4, 5, 6]);
+    assert_eq!(m.into_iter().collect::<Vec<_>>(), &[]);
+}
diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs
index 495165f7786..9240346ace9 100644
--- a/src/liballoc/collections/vec_deque.rs
+++ b/src/liballoc/collections/vec_deque.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-filelength
-
 //! A double-ended queue implemented with a growable ring buffer.
 //!
 //! This queue has `O(1)` amortized inserts and removals from both ends of the
@@ -24,6 +22,9 @@ use crate::collections::CollectionAllocErr;
 use crate::raw_vec::RawVec;
 use crate::vec::Vec;
 
+#[cfg(test)]
+mod tests;
+
 const INITIAL_CAPACITY: usize = 7; // 2^3 - 1
 const MINIMUM_CAPACITY: usize = 1; // 2 - 1
 #[cfg(target_pointer_width = "16")]
@@ -2838,387 +2839,3 @@ impl<T> From<VecDeque<T>> for Vec<T> {
         }
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use ::test;
-
-    use super::VecDeque;
-
-    #[bench]
-    #[cfg(not(miri))] // Miri does not support benchmarks
-    fn bench_push_back_100(b: &mut test::Bencher) {
-        let mut deq = VecDeque::with_capacity(101);
-        b.iter(|| {
-            for i in 0..100 {
-                deq.push_back(i);
-            }
-            deq.head = 0;
-            deq.tail = 0;
-        })
-    }
-
-    #[bench]
-    #[cfg(not(miri))] // Miri does not support benchmarks
-    fn bench_push_front_100(b: &mut test::Bencher) {
-        let mut deq = VecDeque::with_capacity(101);
-        b.iter(|| {
-            for i in 0..100 {
-                deq.push_front(i);
-            }
-            deq.head = 0;
-            deq.tail = 0;
-        })
-    }
-
-    #[bench]
-    #[cfg(not(miri))] // Miri does not support benchmarks
-    fn bench_pop_back_100(b: &mut test::Bencher) {
-        let mut deq = VecDeque::<i32>::with_capacity(101);
-
-        b.iter(|| {
-            deq.head = 100;
-            deq.tail = 0;
-            while !deq.is_empty() {
-                test::black_box(deq.pop_back());
-            }
-        })
-    }
-
-    #[bench]
-    #[cfg(not(miri))] // Miri does not support benchmarks
-    fn bench_pop_front_100(b: &mut test::Bencher) {
-        let mut deq = VecDeque::<i32>::with_capacity(101);
-
-        b.iter(|| {
-            deq.head = 100;
-            deq.tail = 0;
-            while !deq.is_empty() {
-                test::black_box(deq.pop_front());
-            }
-        })
-    }
-
-    #[test]
-    fn test_swap_front_back_remove() {
-        fn test(back: bool) {
-            // This test checks that every single combination of tail position and length is tested.
-            // Capacity 15 should be large enough to cover every case.
-            let mut tester = VecDeque::with_capacity(15);
-            let usable_cap = tester.capacity();
-            let final_len = usable_cap / 2;
-
-            for len in 0..final_len {
-                let expected: VecDeque<_> = if back {
-                    (0..len).collect()
-                } else {
-                    (0..len).rev().collect()
-                };
-                for tail_pos in 0..usable_cap {
-                    tester.tail = tail_pos;
-                    tester.head = tail_pos;
-                    if back {
-                        for i in 0..len * 2 {
-                            tester.push_front(i);
-                        }
-                        for i in 0..len {
-                            assert_eq!(tester.swap_remove_back(i), Some(len * 2 - 1 - i));
-                        }
-                    } else {
-                        for i in 0..len * 2 {
-                            tester.push_back(i);
-                        }
-                        for i in 0..len {
-                            let idx = tester.len() - 1 - i;
-                            assert_eq!(tester.swap_remove_front(idx), Some(len * 2 - 1 - i));
-                        }
-                    }
-                    assert!(tester.tail < tester.cap());
-                    assert!(tester.head < tester.cap());
-                    assert_eq!(tester, expected);
-                }
-            }
-        }
-        test(true);
-        test(false);
-    }
-
-    #[test]
-    fn test_insert() {
-        // This test checks that every single combination of tail position, length, and
-        // insertion position is tested. Capacity 15 should be large enough to cover every case.
-
-        let mut tester = VecDeque::with_capacity(15);
-        // can't guarantee we got 15, so have to get what we got.
-        // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
-        // this test isn't covering what it wants to
-        let cap = tester.capacity();
-
-
-        // len is the length *after* insertion
-        for len in 1..cap {
-            // 0, 1, 2, .., len - 1
-            let expected = (0..).take(len).collect::<VecDeque<_>>();
-            for tail_pos in 0..cap {
-                for to_insert in 0..len {
-                    tester.tail = tail_pos;
-                    tester.head = tail_pos;
-                    for i in 0..len {
-                        if i != to_insert {
-                            tester.push_back(i);
-                        }
-                    }
-                    tester.insert(to_insert, to_insert);
-                    assert!(tester.tail < tester.cap());
-                    assert!(tester.head < tester.cap());
-                    assert_eq!(tester, expected);
-                }
-            }
-        }
-    }
-
-    #[test]
-    fn test_remove() {
-        // This test checks that every single combination of tail position, length, and
-        // removal position is tested. Capacity 15 should be large enough to cover every case.
-
-        let mut tester = VecDeque::with_capacity(15);
-        // can't guarantee we got 15, so have to get what we got.
-        // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
-        // this test isn't covering what it wants to
-        let cap = tester.capacity();
-
-        // len is the length *after* removal
-        for len in 0..cap - 1 {
-            // 0, 1, 2, .., len - 1
-            let expected = (0..).take(len).collect::<VecDeque<_>>();
-            for tail_pos in 0..cap {
-                for to_remove in 0..=len {
-                    tester.tail = tail_pos;
-                    tester.head = tail_pos;
-                    for i in 0..len {
-                        if i == to_remove {
-                            tester.push_back(1234);
-                        }
-                        tester.push_back(i);
-                    }
-                    if to_remove == len {
-                        tester.push_back(1234);
-                    }
-                    tester.remove(to_remove);
-                    assert!(tester.tail < tester.cap());
-                    assert!(tester.head < tester.cap());
-                    assert_eq!(tester, expected);
-                }
-            }
-        }
-    }
-
-    #[test]
-    fn test_drain() {
-        let mut tester: VecDeque<usize> = VecDeque::with_capacity(7);
-
-        let cap = tester.capacity();
-        for len in 0..=cap {
-            for tail in 0..=cap {
-                for drain_start in 0..=len {
-                    for drain_end in drain_start..=len {
-                        tester.tail = tail;
-                        tester.head = tail;
-                        for i in 0..len {
-                            tester.push_back(i);
-                        }
-
-                        // Check that we drain the correct values
-                        let drained: VecDeque<_> = tester.drain(drain_start..drain_end).collect();
-                        let drained_expected: VecDeque<_> = (drain_start..drain_end).collect();
-                        assert_eq!(drained, drained_expected);
-
-                        // We shouldn't have changed the capacity or made the
-                        // head or tail out of bounds
-                        assert_eq!(tester.capacity(), cap);
-                        assert!(tester.tail < tester.cap());
-                        assert!(tester.head < tester.cap());
-
-                        // We should see the correct values in the VecDeque
-                        let expected: VecDeque<_> = (0..drain_start)
-                            .chain(drain_end..len)
-                            .collect();
-                        assert_eq!(expected, tester);
-                    }
-                }
-            }
-        }
-    }
-
-    #[test]
-    fn test_shrink_to_fit() {
-        // This test checks that every single combination of head and tail position,
-        // is tested. Capacity 15 should be large enough to cover every case.
-
-        let mut tester = VecDeque::with_capacity(15);
-        // can't guarantee we got 15, so have to get what we got.
-        // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
-        // this test isn't covering what it wants to
-        let cap = tester.capacity();
-        tester.reserve(63);
-        let max_cap = tester.capacity();
-
-        for len in 0..=cap {
-            // 0, 1, 2, .., len - 1
-            let expected = (0..).take(len).collect::<VecDeque<_>>();
-            for tail_pos in 0..=max_cap {
-                tester.tail = tail_pos;
-                tester.head = tail_pos;
-                tester.reserve(63);
-                for i in 0..len {
-                    tester.push_back(i);
-                }
-                tester.shrink_to_fit();
-                assert!(tester.capacity() <= cap);
-                assert!(tester.tail < tester.cap());
-                assert!(tester.head < tester.cap());
-                assert_eq!(tester, expected);
-            }
-        }
-    }
-
-    #[test]
-    fn test_split_off() {
-        // This test checks that every single combination of tail position, length, and
-        // split position is tested. Capacity 15 should be large enough to cover every case.
-
-        let mut tester = VecDeque::with_capacity(15);
-        // can't guarantee we got 15, so have to get what we got.
-        // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
-        // this test isn't covering what it wants to
-        let cap = tester.capacity();
-
-        // len is the length *before* splitting
-        for len in 0..cap {
-            // index to split at
-            for at in 0..=len {
-                // 0, 1, 2, .., at - 1 (may be empty)
-                let expected_self = (0..).take(at).collect::<VecDeque<_>>();
-                // at, at + 1, .., len - 1 (may be empty)
-                let expected_other = (at..).take(len - at).collect::<VecDeque<_>>();
-
-                for tail_pos in 0..cap {
-                    tester.tail = tail_pos;
-                    tester.head = tail_pos;
-                    for i in 0..len {
-                        tester.push_back(i);
-                    }
-                    let result = tester.split_off(at);
-                    assert!(tester.tail < tester.cap());
-                    assert!(tester.head < tester.cap());
-                    assert!(result.tail < result.cap());
-                    assert!(result.head < result.cap());
-                    assert_eq!(tester, expected_self);
-                    assert_eq!(result, expected_other);
-                }
-            }
-        }
-    }
-
-    #[test]
-    fn test_from_vec() {
-        use crate::vec::Vec;
-        for cap in 0..35 {
-            for len in 0..=cap {
-                let mut vec = Vec::with_capacity(cap);
-                vec.extend(0..len);
-
-                let vd = VecDeque::from(vec.clone());
-                assert!(vd.cap().is_power_of_two());
-                assert_eq!(vd.len(), vec.len());
-                assert!(vd.into_iter().eq(vec));
-            }
-        }
-    }
-
-    #[test]
-    fn test_vec_from_vecdeque() {
-        use crate::vec::Vec;
-
-        fn create_vec_and_test_convert(capacity: usize, offset: usize, len: usize) {
-            let mut vd = VecDeque::with_capacity(capacity);
-            for _ in 0..offset {
-                vd.push_back(0);
-                vd.pop_front();
-            }
-            vd.extend(0..len);
-
-            let vec: Vec<_> = Vec::from(vd.clone());
-            assert_eq!(vec.len(), vd.len());
-            assert!(vec.into_iter().eq(vd));
-        }
-
-        #[cfg(not(miri))] // Miri is too slow
-        let max_pwr = 7;
-        #[cfg(miri)]
-        let max_pwr = 5;
-
-        for cap_pwr in 0..max_pwr {
-            // Make capacity as a (2^x)-1, so that the ring size is 2^x
-            let cap = (2i32.pow(cap_pwr) - 1) as usize;
-
-            // In these cases there is enough free space to solve it with copies
-            for len in 0..((cap + 1) / 2) {
-                // Test contiguous cases
-                for offset in 0..(cap - len) {
-                    create_vec_and_test_convert(cap, offset, len)
-                }
-
-                // Test cases where block at end of buffer is bigger than block at start
-                for offset in (cap - len)..(cap - (len / 2)) {
-                    create_vec_and_test_convert(cap, offset, len)
-                }
-
-                // Test cases where block at start of buffer is bigger than block at end
-                for offset in (cap - (len / 2))..cap {
-                    create_vec_and_test_convert(cap, offset, len)
-                }
-            }
-
-            // Now there's not (necessarily) space to straighten the ring with simple copies,
-            // the ring will use swapping when:
-            // (cap + 1 - offset) > (cap + 1 - len) && (len - (cap + 1 - offset)) > (cap + 1 - len))
-            //  right block size  >   free space    &&      left block size       >    free space
-            for len in ((cap + 1) / 2)..cap {
-                // Test contiguous cases
-                for offset in 0..(cap - len) {
-                    create_vec_and_test_convert(cap, offset, len)
-                }
-
-                // Test cases where block at end of buffer is bigger than block at start
-                for offset in (cap - len)..(cap - (len / 2)) {
-                    create_vec_and_test_convert(cap, offset, len)
-                }
-
-                // Test cases where block at start of buffer is bigger than block at end
-                for offset in (cap - (len / 2))..cap {
-                    create_vec_and_test_convert(cap, offset, len)
-                }
-            }
-        }
-    }
-
-    #[test]
-    fn issue_53529() {
-        use crate::boxed::Box;
-
-        let mut dst = VecDeque::new();
-        dst.push_front(Box::new(1));
-        dst.push_front(Box::new(2));
-        assert_eq!(*dst.pop_back().unwrap(), 1);
-
-        let mut src = VecDeque::new();
-        src.push_front(Box::new(2));
-        dst.append(&mut src);
-        for a in dst {
-            assert_eq!(*a, 2);
-        }
-    }
-
-}
diff --git a/src/liballoc/collections/vec_deque/tests.rs b/src/liballoc/collections/vec_deque/tests.rs
new file mode 100644
index 00000000000..d2535239979
--- /dev/null
+++ b/src/liballoc/collections/vec_deque/tests.rs
@@ -0,0 +1,379 @@
+use super::*;
+
+use ::test;
+
+#[bench]
+#[cfg(not(miri))] // Miri does not support benchmarks
+fn bench_push_back_100(b: &mut test::Bencher) {
+    let mut deq = VecDeque::with_capacity(101);
+    b.iter(|| {
+        for i in 0..100 {
+            deq.push_back(i);
+        }
+        deq.head = 0;
+        deq.tail = 0;
+    })
+}
+
+#[bench]
+#[cfg(not(miri))] // Miri does not support benchmarks
+fn bench_push_front_100(b: &mut test::Bencher) {
+    let mut deq = VecDeque::with_capacity(101);
+    b.iter(|| {
+        for i in 0..100 {
+            deq.push_front(i);
+        }
+        deq.head = 0;
+        deq.tail = 0;
+    })
+}
+
+#[bench]
+#[cfg(not(miri))] // Miri does not support benchmarks
+fn bench_pop_back_100(b: &mut test::Bencher) {
+    let mut deq = VecDeque::<i32>::with_capacity(101);
+
+    b.iter(|| {
+        deq.head = 100;
+        deq.tail = 0;
+        while !deq.is_empty() {
+            test::black_box(deq.pop_back());
+        }
+    })
+}
+
+#[bench]
+#[cfg(not(miri))] // Miri does not support benchmarks
+fn bench_pop_front_100(b: &mut test::Bencher) {
+    let mut deq = VecDeque::<i32>::with_capacity(101);
+
+    b.iter(|| {
+        deq.head = 100;
+        deq.tail = 0;
+        while !deq.is_empty() {
+            test::black_box(deq.pop_front());
+        }
+    })
+}
+
+#[test]
+fn test_swap_front_back_remove() {
+    fn test(back: bool) {
+        // This test checks that every single combination of tail position and length is tested.
+        // Capacity 15 should be large enough to cover every case.
+        let mut tester = VecDeque::with_capacity(15);
+        let usable_cap = tester.capacity();
+        let final_len = usable_cap / 2;
+
+        for len in 0..final_len {
+            let expected: VecDeque<_> = if back {
+                (0..len).collect()
+            } else {
+                (0..len).rev().collect()
+            };
+            for tail_pos in 0..usable_cap {
+                tester.tail = tail_pos;
+                tester.head = tail_pos;
+                if back {
+                    for i in 0..len * 2 {
+                        tester.push_front(i);
+                    }
+                    for i in 0..len {
+                        assert_eq!(tester.swap_remove_back(i), Some(len * 2 - 1 - i));
+                    }
+                } else {
+                    for i in 0..len * 2 {
+                        tester.push_back(i);
+                    }
+                    for i in 0..len {
+                        let idx = tester.len() - 1 - i;
+                        assert_eq!(tester.swap_remove_front(idx), Some(len * 2 - 1 - i));
+                    }
+                }
+                assert!(tester.tail < tester.cap());
+                assert!(tester.head < tester.cap());
+                assert_eq!(tester, expected);
+            }
+        }
+    }
+    test(true);
+    test(false);
+}
+
+#[test]
+fn test_insert() {
+    // This test checks that every single combination of tail position, length, and
+    // insertion position is tested. Capacity 15 should be large enough to cover every case.
+
+    let mut tester = VecDeque::with_capacity(15);
+    // can't guarantee we got 15, so have to get what we got.
+    // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
+    // this test isn't covering what it wants to
+    let cap = tester.capacity();
+
+
+    // len is the length *after* insertion
+    for len in 1..cap {
+        // 0, 1, 2, .., len - 1
+        let expected = (0..).take(len).collect::<VecDeque<_>>();
+        for tail_pos in 0..cap {
+            for to_insert in 0..len {
+                tester.tail = tail_pos;
+                tester.head = tail_pos;
+                for i in 0..len {
+                    if i != to_insert {
+                        tester.push_back(i);
+                    }
+                }
+                tester.insert(to_insert, to_insert);
+                assert!(tester.tail < tester.cap());
+                assert!(tester.head < tester.cap());
+                assert_eq!(tester, expected);
+            }
+        }
+    }
+}
+
+#[test]
+fn test_remove() {
+    // This test checks that every single combination of tail position, length, and
+    // removal position is tested. Capacity 15 should be large enough to cover every case.
+
+    let mut tester = VecDeque::with_capacity(15);
+    // can't guarantee we got 15, so have to get what we got.
+    // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
+    // this test isn't covering what it wants to
+    let cap = tester.capacity();
+
+    // len is the length *after* removal
+    for len in 0..cap - 1 {
+        // 0, 1, 2, .., len - 1
+        let expected = (0..).take(len).collect::<VecDeque<_>>();
+        for tail_pos in 0..cap {
+            for to_remove in 0..=len {
+                tester.tail = tail_pos;
+                tester.head = tail_pos;
+                for i in 0..len {
+                    if i == to_remove {
+                        tester.push_back(1234);
+                    }
+                    tester.push_back(i);
+                }
+                if to_remove == len {
+                    tester.push_back(1234);
+                }
+                tester.remove(to_remove);
+                assert!(tester.tail < tester.cap());
+                assert!(tester.head < tester.cap());
+                assert_eq!(tester, expected);
+            }
+        }
+    }
+}
+
+#[test]
+fn test_drain() {
+    let mut tester: VecDeque<usize> = VecDeque::with_capacity(7);
+
+    let cap = tester.capacity();
+    for len in 0..=cap {
+        for tail in 0..=cap {
+            for drain_start in 0..=len {
+                for drain_end in drain_start..=len {
+                    tester.tail = tail;
+                    tester.head = tail;
+                    for i in 0..len {
+                        tester.push_back(i);
+                    }
+
+                    // Check that we drain the correct values
+                    let drained: VecDeque<_> = tester.drain(drain_start..drain_end).collect();
+                    let drained_expected: VecDeque<_> = (drain_start..drain_end).collect();
+                    assert_eq!(drained, drained_expected);
+
+                    // We shouldn't have changed the capacity or made the
+                    // head or tail out of bounds
+                    assert_eq!(tester.capacity(), cap);
+                    assert!(tester.tail < tester.cap());
+                    assert!(tester.head < tester.cap());
+
+                    // We should see the correct values in the VecDeque
+                    let expected: VecDeque<_> = (0..drain_start)
+                        .chain(drain_end..len)
+                        .collect();
+                    assert_eq!(expected, tester);
+                }
+            }
+        }
+    }
+}
+
+#[test]
+fn test_shrink_to_fit() {
+    // This test checks that every single combination of head and tail position,
+    // is tested. Capacity 15 should be large enough to cover every case.
+
+    let mut tester = VecDeque::with_capacity(15);
+    // can't guarantee we got 15, so have to get what we got.
+    // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
+    // this test isn't covering what it wants to
+    let cap = tester.capacity();
+    tester.reserve(63);
+    let max_cap = tester.capacity();
+
+    for len in 0..=cap {
+        // 0, 1, 2, .., len - 1
+        let expected = (0..).take(len).collect::<VecDeque<_>>();
+        for tail_pos in 0..=max_cap {
+            tester.tail = tail_pos;
+            tester.head = tail_pos;
+            tester.reserve(63);
+            for i in 0..len {
+                tester.push_back(i);
+            }
+            tester.shrink_to_fit();
+            assert!(tester.capacity() <= cap);
+            assert!(tester.tail < tester.cap());
+            assert!(tester.head < tester.cap());
+            assert_eq!(tester, expected);
+        }
+    }
+}
+
+#[test]
+fn test_split_off() {
+    // This test checks that every single combination of tail position, length, and
+    // split position is tested. Capacity 15 should be large enough to cover every case.
+
+    let mut tester = VecDeque::with_capacity(15);
+    // can't guarantee we got 15, so have to get what we got.
+    // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
+    // this test isn't covering what it wants to
+    let cap = tester.capacity();
+
+    // len is the length *before* splitting
+    for len in 0..cap {
+        // index to split at
+        for at in 0..=len {
+            // 0, 1, 2, .., at - 1 (may be empty)
+            let expected_self = (0..).take(at).collect::<VecDeque<_>>();
+            // at, at + 1, .., len - 1 (may be empty)
+            let expected_other = (at..).take(len - at).collect::<VecDeque<_>>();
+
+            for tail_pos in 0..cap {
+                tester.tail = tail_pos;
+                tester.head = tail_pos;
+                for i in 0..len {
+                    tester.push_back(i);
+                }
+                let result = tester.split_off(at);
+                assert!(tester.tail < tester.cap());
+                assert!(tester.head < tester.cap());
+                assert!(result.tail < result.cap());
+                assert!(result.head < result.cap());
+                assert_eq!(tester, expected_self);
+                assert_eq!(result, expected_other);
+            }
+        }
+    }
+}
+
+#[test]
+fn test_from_vec() {
+    use crate::vec::Vec;
+    for cap in 0..35 {
+        for len in 0..=cap {
+            let mut vec = Vec::with_capacity(cap);
+            vec.extend(0..len);
+
+            let vd = VecDeque::from(vec.clone());
+            assert!(vd.cap().is_power_of_two());
+            assert_eq!(vd.len(), vec.len());
+            assert!(vd.into_iter().eq(vec));
+        }
+    }
+}
+
+#[test]
+fn test_vec_from_vecdeque() {
+    use crate::vec::Vec;
+
+    fn create_vec_and_test_convert(capacity: usize, offset: usize, len: usize) {
+        let mut vd = VecDeque::with_capacity(capacity);
+        for _ in 0..offset {
+            vd.push_back(0);
+            vd.pop_front();
+        }
+        vd.extend(0..len);
+
+        let vec: Vec<_> = Vec::from(vd.clone());
+        assert_eq!(vec.len(), vd.len());
+        assert!(vec.into_iter().eq(vd));
+    }
+
+    #[cfg(not(miri))] // Miri is too slow
+    let max_pwr = 7;
+    #[cfg(miri)]
+    let max_pwr = 5;
+
+    for cap_pwr in 0..max_pwr {
+        // Make capacity as a (2^x)-1, so that the ring size is 2^x
+        let cap = (2i32.pow(cap_pwr) - 1) as usize;
+
+        // In these cases there is enough free space to solve it with copies
+        for len in 0..((cap + 1) / 2) {
+            // Test contiguous cases
+            for offset in 0..(cap - len) {
+                create_vec_and_test_convert(cap, offset, len)
+            }
+
+            // Test cases where block at end of buffer is bigger than block at start
+            for offset in (cap - len)..(cap - (len / 2)) {
+                create_vec_and_test_convert(cap, offset, len)
+            }
+
+            // Test cases where block at start of buffer is bigger than block at end
+            for offset in (cap - (len / 2))..cap {
+                create_vec_and_test_convert(cap, offset, len)
+            }
+        }
+
+        // Now there's not (necessarily) space to straighten the ring with simple copies,
+        // the ring will use swapping when:
+        // (cap + 1 - offset) > (cap + 1 - len) && (len - (cap + 1 - offset)) > (cap + 1 - len))
+        //  right block size  >   free space    &&      left block size       >    free space
+        for len in ((cap + 1) / 2)..cap {
+            // Test contiguous cases
+            for offset in 0..(cap - len) {
+                create_vec_and_test_convert(cap, offset, len)
+            }
+
+            // Test cases where block at end of buffer is bigger than block at start
+            for offset in (cap - len)..(cap - (len / 2)) {
+                create_vec_and_test_convert(cap, offset, len)
+            }
+
+            // Test cases where block at start of buffer is bigger than block at end
+            for offset in (cap - (len / 2))..cap {
+                create_vec_and_test_convert(cap, offset, len)
+            }
+        }
+    }
+}
+
+#[test]
+fn issue_53529() {
+    use crate::boxed::Box;
+
+    let mut dst = VecDeque::new();
+    dst.push_front(Box::new(1));
+    dst.push_front(Box::new(2));
+    assert_eq!(*dst.pop_back().unwrap(), 1);
+
+    let mut src = VecDeque::new();
+    src.push_front(Box::new(2));
+    dst.append(&mut src);
+    for a in dst {
+        assert_eq!(*a, 2);
+    }
+}
diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs
index 24336db6b25..0abab45e920 100644
--- a/src/liballoc/raw_vec.rs
+++ b/src/liballoc/raw_vec.rs
@@ -11,6 +11,9 @@ use crate::alloc::{Alloc, Layout, Global, handle_alloc_error};
 use crate::collections::CollectionAllocErr::{self, *};
 use crate::boxed::Box;
 
+#[cfg(test)]
+mod tests;
+
 /// A low-level utility for more ergonomically allocating, reallocating, and deallocating
 /// a buffer of memory on the heap without having to worry about all the corner cases
 /// involved. This type is excellent for building your own data structures like Vec and VecDeque.
@@ -748,82 +751,3 @@ fn alloc_guard(alloc_size: usize) -> Result<(), CollectionAllocErr> {
 fn capacity_overflow() -> ! {
     panic!("capacity overflow")
 }
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn allocator_param() {
-        use crate::alloc::AllocErr;
-
-        // Writing a test of integration between third-party
-        // allocators and RawVec is a little tricky because the RawVec
-        // API does not expose fallible allocation methods, so we
-        // cannot check what happens when allocator is exhausted
-        // (beyond detecting a panic).
-        //
-        // Instead, this just checks that the RawVec methods do at
-        // least go through the Allocator API when it reserves
-        // storage.
-
-        // A dumb allocator that consumes a fixed amount of fuel
-        // before allocation attempts start failing.
-        struct BoundedAlloc { fuel: usize }
-        unsafe impl Alloc for BoundedAlloc {
-            unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
-                let size = layout.size();
-                if size > self.fuel {
-                    return Err(AllocErr);
-                }
-                match Global.alloc(layout) {
-                    ok @ Ok(_) => { self.fuel -= size; ok }
-                    err @ Err(_) => err,
-                }
-            }
-            unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
-                Global.dealloc(ptr, layout)
-            }
-        }
-
-        let a = BoundedAlloc { fuel: 500 };
-        let mut v: RawVec<u8, _> = RawVec::with_capacity_in(50, a);
-        assert_eq!(v.a.fuel, 450);
-        v.reserve(50, 150); // (causes a realloc, thus using 50 + 150 = 200 units of fuel)
-        assert_eq!(v.a.fuel, 250);
-    }
-
-    #[test]
-    fn reserve_does_not_overallocate() {
-        {
-            let mut v: RawVec<u32> = RawVec::new();
-            // First `reserve` allocates like `reserve_exact`
-            v.reserve(0, 9);
-            assert_eq!(9, v.capacity());
-        }
-
-        {
-            let mut v: RawVec<u32> = RawVec::new();
-            v.reserve(0, 7);
-            assert_eq!(7, v.capacity());
-            // 97 if more than double of 7, so `reserve` should work
-            // like `reserve_exact`.
-            v.reserve(7, 90);
-            assert_eq!(97, v.capacity());
-        }
-
-        {
-            let mut v: RawVec<u32> = RawVec::new();
-            v.reserve(0, 12);
-            assert_eq!(12, v.capacity());
-            v.reserve(12, 3);
-            // 3 is less than half of 12, so `reserve` must grow
-            // exponentially. At the time of writing this test grow
-            // factor is 2, so new capacity is 24, however, grow factor
-            // of 1.5 is OK too. Hence `>= 18` in assert.
-            assert!(v.capacity() >= 12 + 12 / 2);
-        }
-    }
-
-
-}
diff --git a/src/liballoc/raw_vec/tests.rs b/src/liballoc/raw_vec/tests.rs
new file mode 100644
index 00000000000..c389898d1ef
--- /dev/null
+++ b/src/liballoc/raw_vec/tests.rs
@@ -0,0 +1,73 @@
+use super::*;
+
+#[test]
+fn allocator_param() {
+    use crate::alloc::AllocErr;
+
+    // Writing a test of integration between third-party
+    // allocators and RawVec is a little tricky because the RawVec
+    // API does not expose fallible allocation methods, so we
+    // cannot check what happens when allocator is exhausted
+    // (beyond detecting a panic).
+    //
+    // Instead, this just checks that the RawVec methods do at
+    // least go through the Allocator API when it reserves
+    // storage.
+
+    // A dumb allocator that consumes a fixed amount of fuel
+    // before allocation attempts start failing.
+    struct BoundedAlloc { fuel: usize }
+    unsafe impl Alloc for BoundedAlloc {
+        unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
+            let size = layout.size();
+            if size > self.fuel {
+                return Err(AllocErr);
+            }
+            match Global.alloc(layout) {
+                ok @ Ok(_) => { self.fuel -= size; ok }
+                err @ Err(_) => err,
+            }
+        }
+        unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
+            Global.dealloc(ptr, layout)
+        }
+    }
+
+    let a = BoundedAlloc { fuel: 500 };
+    let mut v: RawVec<u8, _> = RawVec::with_capacity_in(50, a);
+    assert_eq!(v.a.fuel, 450);
+    v.reserve(50, 150); // (causes a realloc, thus using 50 + 150 = 200 units of fuel)
+    assert_eq!(v.a.fuel, 250);
+}
+
+#[test]
+fn reserve_does_not_overallocate() {
+    {
+        let mut v: RawVec<u32> = RawVec::new();
+        // First `reserve` allocates like `reserve_exact`
+        v.reserve(0, 9);
+        assert_eq!(9, v.capacity());
+    }
+
+    {
+        let mut v: RawVec<u32> = RawVec::new();
+        v.reserve(0, 7);
+        assert_eq!(7, v.capacity());
+        // 97 if more than double of 7, so `reserve` should work
+        // like `reserve_exact`.
+        v.reserve(7, 90);
+        assert_eq!(97, v.capacity());
+    }
+
+    {
+        let mut v: RawVec<u32> = RawVec::new();
+        v.reserve(0, 12);
+        assert_eq!(12, v.capacity());
+        v.reserve(12, 3);
+        // 3 is less than half of 12, so `reserve` must grow
+        // exponentially. At the time of writing this test grow
+        // factor is 2, so new capacity is 24, however, grow factor
+        // of 1.5 is OK too. Hence `>= 18` in assert.
+        assert!(v.capacity() >= 12 + 12 / 2);
+    }
+}
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 0d0ff7c16f1..e33aac3af47 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -252,6 +252,9 @@ use crate::alloc::{Global, Alloc, Layout, box_free, handle_alloc_error};
 use crate::string::String;
 use crate::vec::Vec;
 
+#[cfg(test)]
+mod tests;
+
 struct RcBox<T: ?Sized> {
     strong: Cell<usize>,
     weak: Cell<usize>,
@@ -1851,436 +1854,6 @@ impl<T: ?Sized> RcBoxPtr<T> for RcBox<T> {
     }
 }
 
-#[cfg(test)]
-mod tests {
-    use super::{Rc, Weak};
-    use std::boxed::Box;
-    use std::cell::RefCell;
-    use std::option::Option::{self, None, Some};
-    use std::result::Result::{Err, Ok};
-    use std::mem::drop;
-    use std::clone::Clone;
-    use std::convert::From;
-
-    #[test]
-    fn test_clone() {
-        let x = Rc::new(RefCell::new(5));
-        let y = x.clone();
-        *x.borrow_mut() = 20;
-        assert_eq!(*y.borrow(), 20);
-    }
-
-    #[test]
-    fn test_simple() {
-        let x = Rc::new(5);
-        assert_eq!(*x, 5);
-    }
-
-    #[test]
-    fn test_simple_clone() {
-        let x = Rc::new(5);
-        let y = x.clone();
-        assert_eq!(*x, 5);
-        assert_eq!(*y, 5);
-    }
-
-    #[test]
-    fn test_destructor() {
-        let x: Rc<Box<_>> = Rc::new(box 5);
-        assert_eq!(**x, 5);
-    }
-
-    #[test]
-    fn test_live() {
-        let x = Rc::new(5);
-        let y = Rc::downgrade(&x);
-        assert!(y.upgrade().is_some());
-    }
-
-    #[test]
-    fn test_dead() {
-        let x = Rc::new(5);
-        let y = Rc::downgrade(&x);
-        drop(x);
-        assert!(y.upgrade().is_none());
-    }
-
-    #[test]
-    fn weak_self_cyclic() {
-        struct Cycle {
-            x: RefCell<Option<Weak<Cycle>>>,
-        }
-
-        let a = Rc::new(Cycle { x: RefCell::new(None) });
-        let b = Rc::downgrade(&a.clone());
-        *a.x.borrow_mut() = Some(b);
-
-        // hopefully we don't double-free (or leak)...
-    }
-
-    #[test]
-    fn is_unique() {
-        let x = Rc::new(3);
-        assert!(Rc::is_unique(&x));
-        let y = x.clone();
-        assert!(!Rc::is_unique(&x));
-        drop(y);
-        assert!(Rc::is_unique(&x));
-        let w = Rc::downgrade(&x);
-        assert!(!Rc::is_unique(&x));
-        drop(w);
-        assert!(Rc::is_unique(&x));
-    }
-
-    #[test]
-    fn test_strong_count() {
-        let a = Rc::new(0);
-        assert!(Rc::strong_count(&a) == 1);
-        let w = Rc::downgrade(&a);
-        assert!(Rc::strong_count(&a) == 1);
-        let b = w.upgrade().expect("upgrade of live rc failed");
-        assert!(Rc::strong_count(&b) == 2);
-        assert!(Rc::strong_count(&a) == 2);
-        drop(w);
-        drop(a);
-        assert!(Rc::strong_count(&b) == 1);
-        let c = b.clone();
-        assert!(Rc::strong_count(&b) == 2);
-        assert!(Rc::strong_count(&c) == 2);
-    }
-
-    #[test]
-    fn test_weak_count() {
-        let a = Rc::new(0);
-        assert!(Rc::strong_count(&a) == 1);
-        assert!(Rc::weak_count(&a) == 0);
-        let w = Rc::downgrade(&a);
-        assert!(Rc::strong_count(&a) == 1);
-        assert!(Rc::weak_count(&a) == 1);
-        drop(w);
-        assert!(Rc::strong_count(&a) == 1);
-        assert!(Rc::weak_count(&a) == 0);
-        let c = a.clone();
-        assert!(Rc::strong_count(&a) == 2);
-        assert!(Rc::weak_count(&a) == 0);
-        drop(c);
-    }
-
-    #[test]
-    fn weak_counts() {
-        assert_eq!(Weak::weak_count(&Weak::<u64>::new()), None);
-        assert_eq!(Weak::strong_count(&Weak::<u64>::new()), 0);
-
-        let a = Rc::new(0);
-        let w = Rc::downgrade(&a);
-        assert_eq!(Weak::strong_count(&w), 1);
-        assert_eq!(Weak::weak_count(&w), Some(1));
-        let w2 = w.clone();
-        assert_eq!(Weak::strong_count(&w), 1);
-        assert_eq!(Weak::weak_count(&w), Some(2));
-        assert_eq!(Weak::strong_count(&w2), 1);
-        assert_eq!(Weak::weak_count(&w2), Some(2));
-        drop(w);
-        assert_eq!(Weak::strong_count(&w2), 1);
-        assert_eq!(Weak::weak_count(&w2), Some(1));
-        let a2 = a.clone();
-        assert_eq!(Weak::strong_count(&w2), 2);
-        assert_eq!(Weak::weak_count(&w2), Some(1));
-        drop(a2);
-        drop(a);
-        assert_eq!(Weak::strong_count(&w2), 0);
-        assert_eq!(Weak::weak_count(&w2), Some(1));
-        drop(w2);
-    }
-
-    #[test]
-    fn try_unwrap() {
-        let x = Rc::new(3);
-        assert_eq!(Rc::try_unwrap(x), Ok(3));
-        let x = Rc::new(4);
-        let _y = x.clone();
-        assert_eq!(Rc::try_unwrap(x), Err(Rc::new(4)));
-        let x = Rc::new(5);
-        let _w = Rc::downgrade(&x);
-        assert_eq!(Rc::try_unwrap(x), Ok(5));
-    }
-
-    #[test]
-    fn into_from_raw() {
-        let x = Rc::new(box "hello");
-        let y = x.clone();
-
-        let x_ptr = Rc::into_raw(x);
-        drop(y);
-        unsafe {
-            assert_eq!(**x_ptr, "hello");
-
-            let x = Rc::from_raw(x_ptr);
-            assert_eq!(**x, "hello");
-
-            assert_eq!(Rc::try_unwrap(x).map(|x| *x), Ok("hello"));
-        }
-    }
-
-    #[test]
-    fn test_into_from_raw_unsized() {
-        use std::fmt::Display;
-        use std::string::ToString;
-
-        let rc: Rc<str> = Rc::from("foo");
-
-        let ptr = Rc::into_raw(rc.clone());
-        let rc2 = unsafe { Rc::from_raw(ptr) };
-
-        assert_eq!(unsafe { &*ptr }, "foo");
-        assert_eq!(rc, rc2);
-
-        let rc: Rc<dyn Display> = Rc::new(123);
-
-        let ptr = Rc::into_raw(rc.clone());
-        let rc2 = unsafe { Rc::from_raw(ptr) };
-
-        assert_eq!(unsafe { &*ptr }.to_string(), "123");
-        assert_eq!(rc2.to_string(), "123");
-    }
-
-    #[test]
-    fn get_mut() {
-        let mut x = Rc::new(3);
-        *Rc::get_mut(&mut x).unwrap() = 4;
-        assert_eq!(*x, 4);
-        let y = x.clone();
-        assert!(Rc::get_mut(&mut x).is_none());
-        drop(y);
-        assert!(Rc::get_mut(&mut x).is_some());
-        let _w = Rc::downgrade(&x);
-        assert!(Rc::get_mut(&mut x).is_none());
-    }
-
-    #[test]
-    fn test_cowrc_clone_make_unique() {
-        let mut cow0 = Rc::new(75);
-        let mut cow1 = cow0.clone();
-        let mut cow2 = cow1.clone();
-
-        assert!(75 == *Rc::make_mut(&mut cow0));
-        assert!(75 == *Rc::make_mut(&mut cow1));
-        assert!(75 == *Rc::make_mut(&mut cow2));
-
-        *Rc::make_mut(&mut cow0) += 1;
-        *Rc::make_mut(&mut cow1) += 2;
-        *Rc::make_mut(&mut cow2) += 3;
-
-        assert!(76 == *cow0);
-        assert!(77 == *cow1);
-        assert!(78 == *cow2);
-
-        // none should point to the same backing memory
-        assert!(*cow0 != *cow1);
-        assert!(*cow0 != *cow2);
-        assert!(*cow1 != *cow2);
-    }
-
-    #[test]
-    fn test_cowrc_clone_unique2() {
-        let mut cow0 = Rc::new(75);
-        let cow1 = cow0.clone();
-        let cow2 = cow1.clone();
-
-        assert!(75 == *cow0);
-        assert!(75 == *cow1);
-        assert!(75 == *cow2);
-
-        *Rc::make_mut(&mut cow0) += 1;
-
-        assert!(76 == *cow0);
-        assert!(75 == *cow1);
-        assert!(75 == *cow2);
-
-        // cow1 and cow2 should share the same contents
-        // cow0 should have a unique reference
-        assert!(*cow0 != *cow1);
-        assert!(*cow0 != *cow2);
-        assert!(*cow1 == *cow2);
-    }
-
-    #[test]
-    fn test_cowrc_clone_weak() {
-        let mut cow0 = Rc::new(75);
-        let cow1_weak = Rc::downgrade(&cow0);
-
-        assert!(75 == *cow0);
-        assert!(75 == *cow1_weak.upgrade().unwrap());
-
-        *Rc::make_mut(&mut cow0) += 1;
-
-        assert!(76 == *cow0);
-        assert!(cow1_weak.upgrade().is_none());
-    }
-
-    #[test]
-    fn test_show() {
-        let foo = Rc::new(75);
-        assert_eq!(format!("{:?}", foo), "75");
-    }
-
-    #[test]
-    fn test_unsized() {
-        let foo: Rc<[i32]> = Rc::new([1, 2, 3]);
-        assert_eq!(foo, foo.clone());
-    }
-
-    #[test]
-    fn test_from_owned() {
-        let foo = 123;
-        let foo_rc = Rc::from(foo);
-        assert!(123 == *foo_rc);
-    }
-
-    #[test]
-    fn test_new_weak() {
-        let foo: Weak<usize> = Weak::new();
-        assert!(foo.upgrade().is_none());
-    }
-
-    #[test]
-    fn test_ptr_eq() {
-        let five = Rc::new(5);
-        let same_five = five.clone();
-        let other_five = Rc::new(5);
-
-        assert!(Rc::ptr_eq(&five, &same_five));
-        assert!(!Rc::ptr_eq(&five, &other_five));
-    }
-
-    #[test]
-    fn test_from_str() {
-        let r: Rc<str> = Rc::from("foo");
-
-        assert_eq!(&r[..], "foo");
-    }
-
-    #[test]
-    fn test_copy_from_slice() {
-        let s: &[u32] = &[1, 2, 3];
-        let r: Rc<[u32]> = Rc::from(s);
-
-        assert_eq!(&r[..], [1, 2, 3]);
-    }
-
-    #[test]
-    fn test_clone_from_slice() {
-        #[derive(Clone, Debug, Eq, PartialEq)]
-        struct X(u32);
-
-        let s: &[X] = &[X(1), X(2), X(3)];
-        let r: Rc<[X]> = Rc::from(s);
-
-        assert_eq!(&r[..], s);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_clone_from_slice_panic() {
-        use std::string::{String, ToString};
-
-        struct Fail(u32, String);
-
-        impl Clone for Fail {
-            fn clone(&self) -> Fail {
-                if self.0 == 2 {
-                    panic!();
-                }
-                Fail(self.0, self.1.clone())
-            }
-        }
-
-        let s: &[Fail] = &[
-            Fail(0, "foo".to_string()),
-            Fail(1, "bar".to_string()),
-            Fail(2, "baz".to_string()),
-        ];
-
-        // Should panic, but not cause memory corruption
-        let _r: Rc<[Fail]> = Rc::from(s);
-    }
-
-    #[test]
-    fn test_from_box() {
-        let b: Box<u32> = box 123;
-        let r: Rc<u32> = Rc::from(b);
-
-        assert_eq!(*r, 123);
-    }
-
-    #[test]
-    fn test_from_box_str() {
-        use std::string::String;
-
-        let s = String::from("foo").into_boxed_str();
-        let r: Rc<str> = Rc::from(s);
-
-        assert_eq!(&r[..], "foo");
-    }
-
-    #[test]
-    fn test_from_box_slice() {
-        let s = vec![1, 2, 3].into_boxed_slice();
-        let r: Rc<[u32]> = Rc::from(s);
-
-        assert_eq!(&r[..], [1, 2, 3]);
-    }
-
-    #[test]
-    fn test_from_box_trait() {
-        use std::fmt::Display;
-        use std::string::ToString;
-
-        let b: Box<dyn Display> = box 123;
-        let r: Rc<dyn Display> = Rc::from(b);
-
-        assert_eq!(r.to_string(), "123");
-    }
-
-    #[test]
-    fn test_from_box_trait_zero_sized() {
-        use std::fmt::Debug;
-
-        let b: Box<dyn Debug> = box ();
-        let r: Rc<dyn Debug> = Rc::from(b);
-
-        assert_eq!(format!("{:?}", r), "()");
-    }
-
-    #[test]
-    fn test_from_vec() {
-        let v = vec![1, 2, 3];
-        let r: Rc<[u32]> = Rc::from(v);
-
-        assert_eq!(&r[..], [1, 2, 3]);
-    }
-
-    #[test]
-    fn test_downcast() {
-        use std::any::Any;
-
-        let r1: Rc<dyn Any> = Rc::new(i32::max_value());
-        let r2: Rc<dyn Any> = Rc::new("abc");
-
-        assert!(r1.clone().downcast::<u32>().is_err());
-
-        let r1i32 = r1.downcast::<i32>();
-        assert!(r1i32.is_ok());
-        assert_eq!(r1i32.unwrap(), Rc::new(i32::max_value()));
-
-        assert!(r2.clone().downcast::<i32>().is_err());
-
-        let r2str = r2.downcast::<&'static str>();
-        assert!(r2str.is_ok());
-        assert_eq!(r2str.unwrap(), Rc::new("abc"));
-    }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> borrow::Borrow<T> for Rc<T> {
     fn borrow(&self) -> &T {
diff --git a/src/liballoc/rc/tests.rs b/src/liballoc/rc/tests.rs
new file mode 100644
index 00000000000..72816a5c120
--- /dev/null
+++ b/src/liballoc/rc/tests.rs
@@ -0,0 +1,427 @@
+use super::*;
+
+use std::boxed::Box;
+use std::cell::RefCell;
+use std::option::Option::{self, None, Some};
+use std::result::Result::{Err, Ok};
+use std::mem::drop;
+use std::clone::Clone;
+use std::convert::From;
+
+#[test]
+fn test_clone() {
+    let x = Rc::new(RefCell::new(5));
+    let y = x.clone();
+    *x.borrow_mut() = 20;
+    assert_eq!(*y.borrow(), 20);
+}
+
+#[test]
+fn test_simple() {
+    let x = Rc::new(5);
+    assert_eq!(*x, 5);
+}
+
+#[test]
+fn test_simple_clone() {
+    let x = Rc::new(5);
+    let y = x.clone();
+    assert_eq!(*x, 5);
+    assert_eq!(*y, 5);
+}
+
+#[test]
+fn test_destructor() {
+    let x: Rc<Box<_>> = Rc::new(box 5);
+    assert_eq!(**x, 5);
+}
+
+#[test]
+fn test_live() {
+    let x = Rc::new(5);
+    let y = Rc::downgrade(&x);
+    assert!(y.upgrade().is_some());
+}
+
+#[test]
+fn test_dead() {
+    let x = Rc::new(5);
+    let y = Rc::downgrade(&x);
+    drop(x);
+    assert!(y.upgrade().is_none());
+}
+
+#[test]
+fn weak_self_cyclic() {
+    struct Cycle {
+        x: RefCell<Option<Weak<Cycle>>>,
+    }
+
+    let a = Rc::new(Cycle { x: RefCell::new(None) });
+    let b = Rc::downgrade(&a.clone());
+    *a.x.borrow_mut() = Some(b);
+
+    // hopefully we don't double-free (or leak)...
+}
+
+#[test]
+fn is_unique() {
+    let x = Rc::new(3);
+    assert!(Rc::is_unique(&x));
+    let y = x.clone();
+    assert!(!Rc::is_unique(&x));
+    drop(y);
+    assert!(Rc::is_unique(&x));
+    let w = Rc::downgrade(&x);
+    assert!(!Rc::is_unique(&x));
+    drop(w);
+    assert!(Rc::is_unique(&x));
+}
+
+#[test]
+fn test_strong_count() {
+    let a = Rc::new(0);
+    assert!(Rc::strong_count(&a) == 1);
+    let w = Rc::downgrade(&a);
+    assert!(Rc::strong_count(&a) == 1);
+    let b = w.upgrade().expect("upgrade of live rc failed");
+    assert!(Rc::strong_count(&b) == 2);
+    assert!(Rc::strong_count(&a) == 2);
+    drop(w);
+    drop(a);
+    assert!(Rc::strong_count(&b) == 1);
+    let c = b.clone();
+    assert!(Rc::strong_count(&b) == 2);
+    assert!(Rc::strong_count(&c) == 2);
+}
+
+#[test]
+fn test_weak_count() {
+    let a = Rc::new(0);
+    assert!(Rc::strong_count(&a) == 1);
+    assert!(Rc::weak_count(&a) == 0);
+    let w = Rc::downgrade(&a);
+    assert!(Rc::strong_count(&a) == 1);
+    assert!(Rc::weak_count(&a) == 1);
+    drop(w);
+    assert!(Rc::strong_count(&a) == 1);
+    assert!(Rc::weak_count(&a) == 0);
+    let c = a.clone();
+    assert!(Rc::strong_count(&a) == 2);
+    assert!(Rc::weak_count(&a) == 0);
+    drop(c);
+}
+
+#[test]
+fn weak_counts() {
+    assert_eq!(Weak::weak_count(&Weak::<u64>::new()), None);
+    assert_eq!(Weak::strong_count(&Weak::<u64>::new()), 0);
+
+    let a = Rc::new(0);
+    let w = Rc::downgrade(&a);
+    assert_eq!(Weak::strong_count(&w), 1);
+    assert_eq!(Weak::weak_count(&w), Some(1));
+    let w2 = w.clone();
+    assert_eq!(Weak::strong_count(&w), 1);
+    assert_eq!(Weak::weak_count(&w), Some(2));
+    assert_eq!(Weak::strong_count(&w2), 1);
+    assert_eq!(Weak::weak_count(&w2), Some(2));
+    drop(w);
+    assert_eq!(Weak::strong_count(&w2), 1);
+    assert_eq!(Weak::weak_count(&w2), Some(1));
+    let a2 = a.clone();
+    assert_eq!(Weak::strong_count(&w2), 2);
+    assert_eq!(Weak::weak_count(&w2), Some(1));
+    drop(a2);
+    drop(a);
+    assert_eq!(Weak::strong_count(&w2), 0);
+    assert_eq!(Weak::weak_count(&w2), Some(1));
+    drop(w2);
+}
+
+#[test]
+fn try_unwrap() {
+    let x = Rc::new(3);
+    assert_eq!(Rc::try_unwrap(x), Ok(3));
+    let x = Rc::new(4);
+    let _y = x.clone();
+    assert_eq!(Rc::try_unwrap(x), Err(Rc::new(4)));
+    let x = Rc::new(5);
+    let _w = Rc::downgrade(&x);
+    assert_eq!(Rc::try_unwrap(x), Ok(5));
+}
+
+#[test]
+fn into_from_raw() {
+    let x = Rc::new(box "hello");
+    let y = x.clone();
+
+    let x_ptr = Rc::into_raw(x);
+    drop(y);
+    unsafe {
+        assert_eq!(**x_ptr, "hello");
+
+        let x = Rc::from_raw(x_ptr);
+        assert_eq!(**x, "hello");
+
+        assert_eq!(Rc::try_unwrap(x).map(|x| *x), Ok("hello"));
+    }
+}
+
+#[test]
+fn test_into_from_raw_unsized() {
+    use std::fmt::Display;
+    use std::string::ToString;
+
+    let rc: Rc<str> = Rc::from("foo");
+
+    let ptr = Rc::into_raw(rc.clone());
+    let rc2 = unsafe { Rc::from_raw(ptr) };
+
+    assert_eq!(unsafe { &*ptr }, "foo");
+    assert_eq!(rc, rc2);
+
+    let rc: Rc<dyn Display> = Rc::new(123);
+
+    let ptr = Rc::into_raw(rc.clone());
+    let rc2 = unsafe { Rc::from_raw(ptr) };
+
+    assert_eq!(unsafe { &*ptr }.to_string(), "123");
+    assert_eq!(rc2.to_string(), "123");
+}
+
+#[test]
+fn get_mut() {
+    let mut x = Rc::new(3);
+    *Rc::get_mut(&mut x).unwrap() = 4;
+    assert_eq!(*x, 4);
+    let y = x.clone();
+    assert!(Rc::get_mut(&mut x).is_none());
+    drop(y);
+    assert!(Rc::get_mut(&mut x).is_some());
+    let _w = Rc::downgrade(&x);
+    assert!(Rc::get_mut(&mut x).is_none());
+}
+
+#[test]
+fn test_cowrc_clone_make_unique() {
+    let mut cow0 = Rc::new(75);
+    let mut cow1 = cow0.clone();
+    let mut cow2 = cow1.clone();
+
+    assert!(75 == *Rc::make_mut(&mut cow0));
+    assert!(75 == *Rc::make_mut(&mut cow1));
+    assert!(75 == *Rc::make_mut(&mut cow2));
+
+    *Rc::make_mut(&mut cow0) += 1;
+    *Rc::make_mut(&mut cow1) += 2;
+    *Rc::make_mut(&mut cow2) += 3;
+
+    assert!(76 == *cow0);
+    assert!(77 == *cow1);
+    assert!(78 == *cow2);
+
+    // none should point to the same backing memory
+    assert!(*cow0 != *cow1);
+    assert!(*cow0 != *cow2);
+    assert!(*cow1 != *cow2);
+}
+
+#[test]
+fn test_cowrc_clone_unique2() {
+    let mut cow0 = Rc::new(75);
+    let cow1 = cow0.clone();
+    let cow2 = cow1.clone();
+
+    assert!(75 == *cow0);
+    assert!(75 == *cow1);
+    assert!(75 == *cow2);
+
+    *Rc::make_mut(&mut cow0) += 1;
+
+    assert!(76 == *cow0);
+    assert!(75 == *cow1);
+    assert!(75 == *cow2);
+
+    // cow1 and cow2 should share the same contents
+    // cow0 should have a unique reference
+    assert!(*cow0 != *cow1);
+    assert!(*cow0 != *cow2);
+    assert!(*cow1 == *cow2);
+}
+
+#[test]
+fn test_cowrc_clone_weak() {
+    let mut cow0 = Rc::new(75);
+    let cow1_weak = Rc::downgrade(&cow0);
+
+    assert!(75 == *cow0);
+    assert!(75 == *cow1_weak.upgrade().unwrap());
+
+    *Rc::make_mut(&mut cow0) += 1;
+
+    assert!(76 == *cow0);
+    assert!(cow1_weak.upgrade().is_none());
+}
+
+#[test]
+fn test_show() {
+    let foo = Rc::new(75);
+    assert_eq!(format!("{:?}", foo), "75");
+}
+
+#[test]
+fn test_unsized() {
+    let foo: Rc<[i32]> = Rc::new([1, 2, 3]);
+    assert_eq!(foo, foo.clone());
+}
+
+#[test]
+fn test_from_owned() {
+    let foo = 123;
+    let foo_rc = Rc::from(foo);
+    assert!(123 == *foo_rc);
+}
+
+#[test]
+fn test_new_weak() {
+    let foo: Weak<usize> = Weak::new();
+    assert!(foo.upgrade().is_none());
+}
+
+#[test]
+fn test_ptr_eq() {
+    let five = Rc::new(5);
+    let same_five = five.clone();
+    let other_five = Rc::new(5);
+
+    assert!(Rc::ptr_eq(&five, &same_five));
+    assert!(!Rc::ptr_eq(&five, &other_five));
+}
+
+#[test]
+fn test_from_str() {
+    let r: Rc<str> = Rc::from("foo");
+
+    assert_eq!(&r[..], "foo");
+}
+
+#[test]
+fn test_copy_from_slice() {
+    let s: &[u32] = &[1, 2, 3];
+    let r: Rc<[u32]> = Rc::from(s);
+
+    assert_eq!(&r[..], [1, 2, 3]);
+}
+
+#[test]
+fn test_clone_from_slice() {
+    #[derive(Clone, Debug, Eq, PartialEq)]
+    struct X(u32);
+
+    let s: &[X] = &[X(1), X(2), X(3)];
+    let r: Rc<[X]> = Rc::from(s);
+
+    assert_eq!(&r[..], s);
+}
+
+#[test]
+#[should_panic]
+fn test_clone_from_slice_panic() {
+    use std::string::{String, ToString};
+
+    struct Fail(u32, String);
+
+    impl Clone for Fail {
+        fn clone(&self) -> Fail {
+            if self.0 == 2 {
+                panic!();
+            }
+            Fail(self.0, self.1.clone())
+        }
+    }
+
+    let s: &[Fail] = &[
+        Fail(0, "foo".to_string()),
+        Fail(1, "bar".to_string()),
+        Fail(2, "baz".to_string()),
+    ];
+
+    // Should panic, but not cause memory corruption
+    let _r: Rc<[Fail]> = Rc::from(s);
+}
+
+#[test]
+fn test_from_box() {
+    let b: Box<u32> = box 123;
+    let r: Rc<u32> = Rc::from(b);
+
+    assert_eq!(*r, 123);
+}
+
+#[test]
+fn test_from_box_str() {
+    use std::string::String;
+
+    let s = String::from("foo").into_boxed_str();
+    let r: Rc<str> = Rc::from(s);
+
+    assert_eq!(&r[..], "foo");
+}
+
+#[test]
+fn test_from_box_slice() {
+    let s = vec![1, 2, 3].into_boxed_slice();
+    let r: Rc<[u32]> = Rc::from(s);
+
+    assert_eq!(&r[..], [1, 2, 3]);
+}
+
+#[test]
+fn test_from_box_trait() {
+    use std::fmt::Display;
+    use std::string::ToString;
+
+    let b: Box<dyn Display> = box 123;
+    let r: Rc<dyn Display> = Rc::from(b);
+
+    assert_eq!(r.to_string(), "123");
+}
+
+#[test]
+fn test_from_box_trait_zero_sized() {
+    use std::fmt::Debug;
+
+    let b: Box<dyn Debug> = box ();
+    let r: Rc<dyn Debug> = Rc::from(b);
+
+    assert_eq!(format!("{:?}", r), "()");
+}
+
+#[test]
+fn test_from_vec() {
+    let v = vec![1, 2, 3];
+    let r: Rc<[u32]> = Rc::from(v);
+
+    assert_eq!(&r[..], [1, 2, 3]);
+}
+
+#[test]
+fn test_downcast() {
+    use std::any::Any;
+
+    let r1: Rc<dyn Any> = Rc::new(i32::max_value());
+    let r2: Rc<dyn Any> = Rc::new("abc");
+
+    assert!(r1.clone().downcast::<u32>().is_err());
+
+    let r1i32 = r1.downcast::<i32>();
+    assert!(r1i32.is_ok());
+    assert_eq!(r1i32.unwrap(), Rc::new(i32::max_value()));
+
+    assert!(r2.clone().downcast::<i32>().is_err());
+
+    let r2str = r2.downcast::<&'static str>();
+    assert!(r2str.is_ok());
+    assert_eq!(r2str.unwrap(), Rc::new("abc"));
+}
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index 93aff733724..e11873218e8 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -30,6 +30,9 @@ use crate::rc::is_dangling;
 use crate::string::String;
 use crate::vec::Vec;
 
+#[cfg(test)]
+mod tests;
+
 /// A soft limit on the amount of references that may be made to an `Arc`.
 ///
 /// Going above this limit will abort your program (although not
@@ -1915,489 +1918,6 @@ impl<'a, T: 'a + Clone> ArcFromIter<&'a T, slice::Iter<'a, T>> for Arc<[T]> {
     }
 }
 
-#[cfg(test)]
-mod tests {
-    use std::boxed::Box;
-    use std::clone::Clone;
-    use std::sync::mpsc::channel;
-    use std::mem::drop;
-    use std::ops::Drop;
-    use std::option::Option::{self, None, Some};
-    use std::sync::atomic::{self, Ordering::{Acquire, SeqCst}};
-    use std::thread;
-    use std::sync::Mutex;
-    use std::convert::From;
-
-    use super::{Arc, Weak};
-    use crate::vec::Vec;
-
-    struct Canary(*mut atomic::AtomicUsize);
-
-    impl Drop for Canary {
-        fn drop(&mut self) {
-            unsafe {
-                match *self {
-                    Canary(c) => {
-                        (*c).fetch_add(1, SeqCst);
-                    }
-                }
-            }
-        }
-    }
-
-    #[test]
-    #[cfg_attr(target_os = "emscripten", ignore)]
-    #[cfg(not(miri))] // Miri does not support threads
-    fn manually_share_arc() {
-        let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-        let arc_v = Arc::new(v);
-
-        let (tx, rx) = channel();
-
-        let _t = thread::spawn(move || {
-            let arc_v: Arc<Vec<i32>> = rx.recv().unwrap();
-            assert_eq!((*arc_v)[3], 4);
-        });
-
-        tx.send(arc_v.clone()).unwrap();
-
-        assert_eq!((*arc_v)[2], 3);
-        assert_eq!((*arc_v)[4], 5);
-    }
-
-    #[test]
-    fn test_arc_get_mut() {
-        let mut x = Arc::new(3);
-        *Arc::get_mut(&mut x).unwrap() = 4;
-        assert_eq!(*x, 4);
-        let y = x.clone();
-        assert!(Arc::get_mut(&mut x).is_none());
-        drop(y);
-        assert!(Arc::get_mut(&mut x).is_some());
-        let _w = Arc::downgrade(&x);
-        assert!(Arc::get_mut(&mut x).is_none());
-    }
-
-    #[test]
-    fn weak_counts() {
-        assert_eq!(Weak::weak_count(&Weak::<u64>::new()), None);
-        assert_eq!(Weak::strong_count(&Weak::<u64>::new()), 0);
-
-        let a = Arc::new(0);
-        let w = Arc::downgrade(&a);
-        assert_eq!(Weak::strong_count(&w), 1);
-        assert_eq!(Weak::weak_count(&w), Some(1));
-        let w2 = w.clone();
-        assert_eq!(Weak::strong_count(&w), 1);
-        assert_eq!(Weak::weak_count(&w), Some(2));
-        assert_eq!(Weak::strong_count(&w2), 1);
-        assert_eq!(Weak::weak_count(&w2), Some(2));
-        drop(w);
-        assert_eq!(Weak::strong_count(&w2), 1);
-        assert_eq!(Weak::weak_count(&w2), Some(1));
-        let a2 = a.clone();
-        assert_eq!(Weak::strong_count(&w2), 2);
-        assert_eq!(Weak::weak_count(&w2), Some(1));
-        drop(a2);
-        drop(a);
-        assert_eq!(Weak::strong_count(&w2), 0);
-        assert_eq!(Weak::weak_count(&w2), Some(1));
-        drop(w2);
-    }
-
-    #[test]
-    fn try_unwrap() {
-        let x = Arc::new(3);
-        assert_eq!(Arc::try_unwrap(x), Ok(3));
-        let x = Arc::new(4);
-        let _y = x.clone();
-        assert_eq!(Arc::try_unwrap(x), Err(Arc::new(4)));
-        let x = Arc::new(5);
-        let _w = Arc::downgrade(&x);
-        assert_eq!(Arc::try_unwrap(x), Ok(5));
-    }
-
-    #[test]
-    fn into_from_raw() {
-        let x = Arc::new(box "hello");
-        let y = x.clone();
-
-        let x_ptr = Arc::into_raw(x);
-        drop(y);
-        unsafe {
-            assert_eq!(**x_ptr, "hello");
-
-            let x = Arc::from_raw(x_ptr);
-            assert_eq!(**x, "hello");
-
-            assert_eq!(Arc::try_unwrap(x).map(|x| *x), Ok("hello"));
-        }
-    }
-
-    #[test]
-    fn test_into_from_raw_unsized() {
-        use std::fmt::Display;
-        use std::string::ToString;
-
-        let arc: Arc<str> = Arc::from("foo");
-
-        let ptr = Arc::into_raw(arc.clone());
-        let arc2 = unsafe { Arc::from_raw(ptr) };
-
-        assert_eq!(unsafe { &*ptr }, "foo");
-        assert_eq!(arc, arc2);
-
-        let arc: Arc<dyn Display> = Arc::new(123);
-
-        let ptr = Arc::into_raw(arc.clone());
-        let arc2 = unsafe { Arc::from_raw(ptr) };
-
-        assert_eq!(unsafe { &*ptr }.to_string(), "123");
-        assert_eq!(arc2.to_string(), "123");
-    }
-
-    #[test]
-    fn test_cowarc_clone_make_mut() {
-        let mut cow0 = Arc::new(75);
-        let mut cow1 = cow0.clone();
-        let mut cow2 = cow1.clone();
-
-        assert!(75 == *Arc::make_mut(&mut cow0));
-        assert!(75 == *Arc::make_mut(&mut cow1));
-        assert!(75 == *Arc::make_mut(&mut cow2));
-
-        *Arc::make_mut(&mut cow0) += 1;
-        *Arc::make_mut(&mut cow1) += 2;
-        *Arc::make_mut(&mut cow2) += 3;
-
-        assert!(76 == *cow0);
-        assert!(77 == *cow1);
-        assert!(78 == *cow2);
-
-        // none should point to the same backing memory
-        assert!(*cow0 != *cow1);
-        assert!(*cow0 != *cow2);
-        assert!(*cow1 != *cow2);
-    }
-
-    #[test]
-    fn test_cowarc_clone_unique2() {
-        let mut cow0 = Arc::new(75);
-        let cow1 = cow0.clone();
-        let cow2 = cow1.clone();
-
-        assert!(75 == *cow0);
-        assert!(75 == *cow1);
-        assert!(75 == *cow2);
-
-        *Arc::make_mut(&mut cow0) += 1;
-        assert!(76 == *cow0);
-        assert!(75 == *cow1);
-        assert!(75 == *cow2);
-
-        // cow1 and cow2 should share the same contents
-        // cow0 should have a unique reference
-        assert!(*cow0 != *cow1);
-        assert!(*cow0 != *cow2);
-        assert!(*cow1 == *cow2);
-    }
-
-    #[test]
-    fn test_cowarc_clone_weak() {
-        let mut cow0 = Arc::new(75);
-        let cow1_weak = Arc::downgrade(&cow0);
-
-        assert!(75 == *cow0);
-        assert!(75 == *cow1_weak.upgrade().unwrap());
-
-        *Arc::make_mut(&mut cow0) += 1;
-
-        assert!(76 == *cow0);
-        assert!(cow1_weak.upgrade().is_none());
-    }
-
-    #[test]
-    fn test_live() {
-        let x = Arc::new(5);
-        let y = Arc::downgrade(&x);
-        assert!(y.upgrade().is_some());
-    }
-
-    #[test]
-    fn test_dead() {
-        let x = Arc::new(5);
-        let y = Arc::downgrade(&x);
-        drop(x);
-        assert!(y.upgrade().is_none());
-    }
-
-    #[test]
-    fn weak_self_cyclic() {
-        struct Cycle {
-            x: Mutex<Option<Weak<Cycle>>>,
-        }
-
-        let a = Arc::new(Cycle { x: Mutex::new(None) });
-        let b = Arc::downgrade(&a.clone());
-        *a.x.lock().unwrap() = Some(b);
-
-        // hopefully we don't double-free (or leak)...
-    }
-
-    #[test]
-    fn drop_arc() {
-        let mut canary = atomic::AtomicUsize::new(0);
-        let x = Arc::new(Canary(&mut canary as *mut atomic::AtomicUsize));
-        drop(x);
-        assert!(canary.load(Acquire) == 1);
-    }
-
-    #[test]
-    fn drop_arc_weak() {
-        let mut canary = atomic::AtomicUsize::new(0);
-        let arc = Arc::new(Canary(&mut canary as *mut atomic::AtomicUsize));
-        let arc_weak = Arc::downgrade(&arc);
-        assert!(canary.load(Acquire) == 0);
-        drop(arc);
-        assert!(canary.load(Acquire) == 1);
-        drop(arc_weak);
-    }
-
-    #[test]
-    fn test_strong_count() {
-        let a = Arc::new(0);
-        assert!(Arc::strong_count(&a) == 1);
-        let w = Arc::downgrade(&a);
-        assert!(Arc::strong_count(&a) == 1);
-        let b = w.upgrade().expect("");
-        assert!(Arc::strong_count(&b) == 2);
-        assert!(Arc::strong_count(&a) == 2);
-        drop(w);
-        drop(a);
-        assert!(Arc::strong_count(&b) == 1);
-        let c = b.clone();
-        assert!(Arc::strong_count(&b) == 2);
-        assert!(Arc::strong_count(&c) == 2);
-    }
-
-    #[test]
-    fn test_weak_count() {
-        let a = Arc::new(0);
-        assert!(Arc::strong_count(&a) == 1);
-        assert!(Arc::weak_count(&a) == 0);
-        let w = Arc::downgrade(&a);
-        assert!(Arc::strong_count(&a) == 1);
-        assert!(Arc::weak_count(&a) == 1);
-        let x = w.clone();
-        assert!(Arc::weak_count(&a) == 2);
-        drop(w);
-        drop(x);
-        assert!(Arc::strong_count(&a) == 1);
-        assert!(Arc::weak_count(&a) == 0);
-        let c = a.clone();
-        assert!(Arc::strong_count(&a) == 2);
-        assert!(Arc::weak_count(&a) == 0);
-        let d = Arc::downgrade(&c);
-        assert!(Arc::weak_count(&c) == 1);
-        assert!(Arc::strong_count(&c) == 2);
-
-        drop(a);
-        drop(c);
-        drop(d);
-    }
-
-    #[test]
-    fn show_arc() {
-        let a = Arc::new(5);
-        assert_eq!(format!("{:?}", a), "5");
-    }
-
-    // Make sure deriving works with Arc<T>
-    #[derive(Eq, Ord, PartialEq, PartialOrd, Clone, Debug, Default)]
-    struct Foo {
-        inner: Arc<i32>,
-    }
-
-    #[test]
-    fn test_unsized() {
-        let x: Arc<[i32]> = Arc::new([1, 2, 3]);
-        assert_eq!(format!("{:?}", x), "[1, 2, 3]");
-        let y = Arc::downgrade(&x.clone());
-        drop(x);
-        assert!(y.upgrade().is_none());
-    }
-
-    #[test]
-    fn test_from_owned() {
-        let foo = 123;
-        let foo_arc = Arc::from(foo);
-        assert!(123 == *foo_arc);
-    }
-
-    #[test]
-    fn test_new_weak() {
-        let foo: Weak<usize> = Weak::new();
-        assert!(foo.upgrade().is_none());
-    }
-
-    #[test]
-    fn test_ptr_eq() {
-        let five = Arc::new(5);
-        let same_five = five.clone();
-        let other_five = Arc::new(5);
-
-        assert!(Arc::ptr_eq(&five, &same_five));
-        assert!(!Arc::ptr_eq(&five, &other_five));
-    }
-
-    #[test]
-    #[cfg_attr(target_os = "emscripten", ignore)]
-    #[cfg(not(miri))] // Miri does not support threads
-    fn test_weak_count_locked() {
-        let mut a = Arc::new(atomic::AtomicBool::new(false));
-        let a2 = a.clone();
-        let t = thread::spawn(move || {
-            for _i in 0..1000000 {
-                Arc::get_mut(&mut a);
-            }
-            a.store(true, SeqCst);
-        });
-
-        while !a2.load(SeqCst) {
-            let n = Arc::weak_count(&a2);
-            assert!(n < 2, "bad weak count: {}", n);
-        }
-        t.join().unwrap();
-    }
-
-    #[test]
-    fn test_from_str() {
-        let r: Arc<str> = Arc::from("foo");
-
-        assert_eq!(&r[..], "foo");
-    }
-
-    #[test]
-    fn test_copy_from_slice() {
-        let s: &[u32] = &[1, 2, 3];
-        let r: Arc<[u32]> = Arc::from(s);
-
-        assert_eq!(&r[..], [1, 2, 3]);
-    }
-
-    #[test]
-    fn test_clone_from_slice() {
-        #[derive(Clone, Debug, Eq, PartialEq)]
-        struct X(u32);
-
-        let s: &[X] = &[X(1), X(2), X(3)];
-        let r: Arc<[X]> = Arc::from(s);
-
-        assert_eq!(&r[..], s);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_clone_from_slice_panic() {
-        use std::string::{String, ToString};
-
-        struct Fail(u32, String);
-
-        impl Clone for Fail {
-            fn clone(&self) -> Fail {
-                if self.0 == 2 {
-                    panic!();
-                }
-                Fail(self.0, self.1.clone())
-            }
-        }
-
-        let s: &[Fail] = &[
-            Fail(0, "foo".to_string()),
-            Fail(1, "bar".to_string()),
-            Fail(2, "baz".to_string()),
-        ];
-
-        // Should panic, but not cause memory corruption
-        let _r: Arc<[Fail]> = Arc::from(s);
-    }
-
-    #[test]
-    fn test_from_box() {
-        let b: Box<u32> = box 123;
-        let r: Arc<u32> = Arc::from(b);
-
-        assert_eq!(*r, 123);
-    }
-
-    #[test]
-    fn test_from_box_str() {
-        use std::string::String;
-
-        let s = String::from("foo").into_boxed_str();
-        let r: Arc<str> = Arc::from(s);
-
-        assert_eq!(&r[..], "foo");
-    }
-
-    #[test]
-    fn test_from_box_slice() {
-        let s = vec![1, 2, 3].into_boxed_slice();
-        let r: Arc<[u32]> = Arc::from(s);
-
-        assert_eq!(&r[..], [1, 2, 3]);
-    }
-
-    #[test]
-    fn test_from_box_trait() {
-        use std::fmt::Display;
-        use std::string::ToString;
-
-        let b: Box<dyn Display> = box 123;
-        let r: Arc<dyn Display> = Arc::from(b);
-
-        assert_eq!(r.to_string(), "123");
-    }
-
-    #[test]
-    fn test_from_box_trait_zero_sized() {
-        use std::fmt::Debug;
-
-        let b: Box<dyn Debug> = box ();
-        let r: Arc<dyn Debug> = Arc::from(b);
-
-        assert_eq!(format!("{:?}", r), "()");
-    }
-
-    #[test]
-    fn test_from_vec() {
-        let v = vec![1, 2, 3];
-        let r: Arc<[u32]> = Arc::from(v);
-
-        assert_eq!(&r[..], [1, 2, 3]);
-    }
-
-    #[test]
-    fn test_downcast() {
-        use std::any::Any;
-
-        let r1: Arc<dyn Any + Send + Sync> = Arc::new(i32::max_value());
-        let r2: Arc<dyn Any + Send + Sync> = Arc::new("abc");
-
-        assert!(r1.clone().downcast::<u32>().is_err());
-
-        let r1i32 = r1.downcast::<i32>();
-        assert!(r1i32.is_ok());
-        assert_eq!(r1i32.unwrap(), Arc::new(i32::max_value()));
-
-        assert!(r2.clone().downcast::<i32>().is_err());
-
-        let r2str = r2.downcast::<&'static str>();
-        assert!(r2str.is_ok());
-        assert_eq!(r2str.unwrap(), Arc::new("abc"));
-    }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> borrow::Borrow<T> for Arc<T> {
     fn borrow(&self) -> &T {
diff --git a/src/liballoc/sync/tests.rs b/src/liballoc/sync/tests.rs
new file mode 100644
index 00000000000..2e0c62f50c1
--- /dev/null
+++ b/src/liballoc/sync/tests.rs
@@ -0,0 +1,480 @@
+use super::*;
+
+use std::boxed::Box;
+use std::clone::Clone;
+use std::sync::mpsc::channel;
+use std::mem::drop;
+use std::ops::Drop;
+use std::option::Option::{self, None, Some};
+use std::sync::atomic::{self, Ordering::{Acquire, SeqCst}};
+use std::thread;
+use std::sync::Mutex;
+use std::convert::From;
+
+use crate::vec::Vec;
+
+struct Canary(*mut atomic::AtomicUsize);
+
+impl Drop for Canary {
+    fn drop(&mut self) {
+        unsafe {
+            match *self {
+                Canary(c) => {
+                    (*c).fetch_add(1, SeqCst);
+                }
+            }
+        }
+    }
+}
+
+#[test]
+#[cfg_attr(target_os = "emscripten", ignore)]
+#[cfg(not(miri))] // Miri does not support threads
+fn manually_share_arc() {
+    let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+    let arc_v = Arc::new(v);
+
+    let (tx, rx) = channel();
+
+    let _t = thread::spawn(move || {
+        let arc_v: Arc<Vec<i32>> = rx.recv().unwrap();
+        assert_eq!((*arc_v)[3], 4);
+    });
+
+    tx.send(arc_v.clone()).unwrap();
+
+    assert_eq!((*arc_v)[2], 3);
+    assert_eq!((*arc_v)[4], 5);
+}
+
+#[test]
+fn test_arc_get_mut() {
+    let mut x = Arc::new(3);
+    *Arc::get_mut(&mut x).unwrap() = 4;
+    assert_eq!(*x, 4);
+    let y = x.clone();
+    assert!(Arc::get_mut(&mut x).is_none());
+    drop(y);
+    assert!(Arc::get_mut(&mut x).is_some());
+    let _w = Arc::downgrade(&x);
+    assert!(Arc::get_mut(&mut x).is_none());
+}
+
+#[test]
+fn weak_counts() {
+    assert_eq!(Weak::weak_count(&Weak::<u64>::new()), None);
+    assert_eq!(Weak::strong_count(&Weak::<u64>::new()), 0);
+
+    let a = Arc::new(0);
+    let w = Arc::downgrade(&a);
+    assert_eq!(Weak::strong_count(&w), 1);
+    assert_eq!(Weak::weak_count(&w), Some(1));
+    let w2 = w.clone();
+    assert_eq!(Weak::strong_count(&w), 1);
+    assert_eq!(Weak::weak_count(&w), Some(2));
+    assert_eq!(Weak::strong_count(&w2), 1);
+    assert_eq!(Weak::weak_count(&w2), Some(2));
+    drop(w);
+    assert_eq!(Weak::strong_count(&w2), 1);
+    assert_eq!(Weak::weak_count(&w2), Some(1));
+    let a2 = a.clone();
+    assert_eq!(Weak::strong_count(&w2), 2);
+    assert_eq!(Weak::weak_count(&w2), Some(1));
+    drop(a2);
+    drop(a);
+    assert_eq!(Weak::strong_count(&w2), 0);
+    assert_eq!(Weak::weak_count(&w2), Some(1));
+    drop(w2);
+}
+
+#[test]
+fn try_unwrap() {
+    let x = Arc::new(3);
+    assert_eq!(Arc::try_unwrap(x), Ok(3));
+    let x = Arc::new(4);
+    let _y = x.clone();
+    assert_eq!(Arc::try_unwrap(x), Err(Arc::new(4)));
+    let x = Arc::new(5);
+    let _w = Arc::downgrade(&x);
+    assert_eq!(Arc::try_unwrap(x), Ok(5));
+}
+
+#[test]
+fn into_from_raw() {
+    let x = Arc::new(box "hello");
+    let y = x.clone();
+
+    let x_ptr = Arc::into_raw(x);
+    drop(y);
+    unsafe {
+        assert_eq!(**x_ptr, "hello");
+
+        let x = Arc::from_raw(x_ptr);
+        assert_eq!(**x, "hello");
+
+        assert_eq!(Arc::try_unwrap(x).map(|x| *x), Ok("hello"));
+    }
+}
+
+#[test]
+fn test_into_from_raw_unsized() {
+    use std::fmt::Display;
+    use std::string::ToString;
+
+    let arc: Arc<str> = Arc::from("foo");
+
+    let ptr = Arc::into_raw(arc.clone());
+    let arc2 = unsafe { Arc::from_raw(ptr) };
+
+    assert_eq!(unsafe { &*ptr }, "foo");
+    assert_eq!(arc, arc2);
+
+    let arc: Arc<dyn Display> = Arc::new(123);
+
+    let ptr = Arc::into_raw(arc.clone());
+    let arc2 = unsafe { Arc::from_raw(ptr) };
+
+    assert_eq!(unsafe { &*ptr }.to_string(), "123");
+    assert_eq!(arc2.to_string(), "123");
+}
+
+#[test]
+fn test_cowarc_clone_make_mut() {
+    let mut cow0 = Arc::new(75);
+    let mut cow1 = cow0.clone();
+    let mut cow2 = cow1.clone();
+
+    assert!(75 == *Arc::make_mut(&mut cow0));
+    assert!(75 == *Arc::make_mut(&mut cow1));
+    assert!(75 == *Arc::make_mut(&mut cow2));
+
+    *Arc::make_mut(&mut cow0) += 1;
+    *Arc::make_mut(&mut cow1) += 2;
+    *Arc::make_mut(&mut cow2) += 3;
+
+    assert!(76 == *cow0);
+    assert!(77 == *cow1);
+    assert!(78 == *cow2);
+
+    // none should point to the same backing memory
+    assert!(*cow0 != *cow1);
+    assert!(*cow0 != *cow2);
+    assert!(*cow1 != *cow2);
+}
+
+#[test]
+fn test_cowarc_clone_unique2() {
+    let mut cow0 = Arc::new(75);
+    let cow1 = cow0.clone();
+    let cow2 = cow1.clone();
+
+    assert!(75 == *cow0);
+    assert!(75 == *cow1);
+    assert!(75 == *cow2);
+
+    *Arc::make_mut(&mut cow0) += 1;
+    assert!(76 == *cow0);
+    assert!(75 == *cow1);
+    assert!(75 == *cow2);
+
+    // cow1 and cow2 should share the same contents
+    // cow0 should have a unique reference
+    assert!(*cow0 != *cow1);
+    assert!(*cow0 != *cow2);
+    assert!(*cow1 == *cow2);
+}
+
+#[test]
+fn test_cowarc_clone_weak() {
+    let mut cow0 = Arc::new(75);
+    let cow1_weak = Arc::downgrade(&cow0);
+
+    assert!(75 == *cow0);
+    assert!(75 == *cow1_weak.upgrade().unwrap());
+
+    *Arc::make_mut(&mut cow0) += 1;
+
+    assert!(76 == *cow0);
+    assert!(cow1_weak.upgrade().is_none());
+}
+
+#[test]
+fn test_live() {
+    let x = Arc::new(5);
+    let y = Arc::downgrade(&x);
+    assert!(y.upgrade().is_some());
+}
+
+#[test]
+fn test_dead() {
+    let x = Arc::new(5);
+    let y = Arc::downgrade(&x);
+    drop(x);
+    assert!(y.upgrade().is_none());
+}
+
+#[test]
+fn weak_self_cyclic() {
+    struct Cycle {
+        x: Mutex<Option<Weak<Cycle>>>,
+    }
+
+    let a = Arc::new(Cycle { x: Mutex::new(None) });
+    let b = Arc::downgrade(&a.clone());
+    *a.x.lock().unwrap() = Some(b);
+
+    // hopefully we don't double-free (or leak)...
+}
+
+#[test]
+fn drop_arc() {
+    let mut canary = atomic::AtomicUsize::new(0);
+    let x = Arc::new(Canary(&mut canary as *mut atomic::AtomicUsize));
+    drop(x);
+    assert!(canary.load(Acquire) == 1);
+}
+
+#[test]
+fn drop_arc_weak() {
+    let mut canary = atomic::AtomicUsize::new(0);
+    let arc = Arc::new(Canary(&mut canary as *mut atomic::AtomicUsize));
+    let arc_weak = Arc::downgrade(&arc);
+    assert!(canary.load(Acquire) == 0);
+    drop(arc);
+    assert!(canary.load(Acquire) == 1);
+    drop(arc_weak);
+}
+
+#[test]
+fn test_strong_count() {
+    let a = Arc::new(0);
+    assert!(Arc::strong_count(&a) == 1);
+    let w = Arc::downgrade(&a);
+    assert!(Arc::strong_count(&a) == 1);
+    let b = w.upgrade().expect("");
+    assert!(Arc::strong_count(&b) == 2);
+    assert!(Arc::strong_count(&a) == 2);
+    drop(w);
+    drop(a);
+    assert!(Arc::strong_count(&b) == 1);
+    let c = b.clone();
+    assert!(Arc::strong_count(&b) == 2);
+    assert!(Arc::strong_count(&c) == 2);
+}
+
+#[test]
+fn test_weak_count() {
+    let a = Arc::new(0);
+    assert!(Arc::strong_count(&a) == 1);
+    assert!(Arc::weak_count(&a) == 0);
+    let w = Arc::downgrade(&a);
+    assert!(Arc::strong_count(&a) == 1);
+    assert!(Arc::weak_count(&a) == 1);
+    let x = w.clone();
+    assert!(Arc::weak_count(&a) == 2);
+    drop(w);
+    drop(x);
+    assert!(Arc::strong_count(&a) == 1);
+    assert!(Arc::weak_count(&a) == 0);
+    let c = a.clone();
+    assert!(Arc::strong_count(&a) == 2);
+    assert!(Arc::weak_count(&a) == 0);
+    let d = Arc::downgrade(&c);
+    assert!(Arc::weak_count(&c) == 1);
+    assert!(Arc::strong_count(&c) == 2);
+
+    drop(a);
+    drop(c);
+    drop(d);
+}
+
+#[test]
+fn show_arc() {
+    let a = Arc::new(5);
+    assert_eq!(format!("{:?}", a), "5");
+}
+
+// Make sure deriving works with Arc<T>
+#[derive(Eq, Ord, PartialEq, PartialOrd, Clone, Debug, Default)]
+struct Foo {
+    inner: Arc<i32>,
+}
+
+#[test]
+fn test_unsized() {
+    let x: Arc<[i32]> = Arc::new([1, 2, 3]);
+    assert_eq!(format!("{:?}", x), "[1, 2, 3]");
+    let y = Arc::downgrade(&x.clone());
+    drop(x);
+    assert!(y.upgrade().is_none());
+}
+
+#[test]
+fn test_from_owned() {
+    let foo = 123;
+    let foo_arc = Arc::from(foo);
+    assert!(123 == *foo_arc);
+}
+
+#[test]
+fn test_new_weak() {
+    let foo: Weak<usize> = Weak::new();
+    assert!(foo.upgrade().is_none());
+}
+
+#[test]
+fn test_ptr_eq() {
+    let five = Arc::new(5);
+    let same_five = five.clone();
+    let other_five = Arc::new(5);
+
+    assert!(Arc::ptr_eq(&five, &same_five));
+    assert!(!Arc::ptr_eq(&five, &other_five));
+}
+
+#[test]
+#[cfg_attr(target_os = "emscripten", ignore)]
+#[cfg(not(miri))] // Miri does not support threads
+fn test_weak_count_locked() {
+    let mut a = Arc::new(atomic::AtomicBool::new(false));
+    let a2 = a.clone();
+    let t = thread::spawn(move || {
+        for _i in 0..1000000 {
+            Arc::get_mut(&mut a);
+        }
+        a.store(true, SeqCst);
+    });
+
+    while !a2.load(SeqCst) {
+        let n = Arc::weak_count(&a2);
+        assert!(n < 2, "bad weak count: {}", n);
+    }
+    t.join().unwrap();
+}
+
+#[test]
+fn test_from_str() {
+    let r: Arc<str> = Arc::from("foo");
+
+    assert_eq!(&r[..], "foo");
+}
+
+#[test]
+fn test_copy_from_slice() {
+    let s: &[u32] = &[1, 2, 3];
+    let r: Arc<[u32]> = Arc::from(s);
+
+    assert_eq!(&r[..], [1, 2, 3]);
+}
+
+#[test]
+fn test_clone_from_slice() {
+    #[derive(Clone, Debug, Eq, PartialEq)]
+    struct X(u32);
+
+    let s: &[X] = &[X(1), X(2), X(3)];
+    let r: Arc<[X]> = Arc::from(s);
+
+    assert_eq!(&r[..], s);
+}
+
+#[test]
+#[should_panic]
+fn test_clone_from_slice_panic() {
+    use std::string::{String, ToString};
+
+    struct Fail(u32, String);
+
+    impl Clone for Fail {
+        fn clone(&self) -> Fail {
+            if self.0 == 2 {
+                panic!();
+            }
+            Fail(self.0, self.1.clone())
+        }
+    }
+
+    let s: &[Fail] = &[
+        Fail(0, "foo".to_string()),
+        Fail(1, "bar".to_string()),
+        Fail(2, "baz".to_string()),
+    ];
+
+    // Should panic, but not cause memory corruption
+    let _r: Arc<[Fail]> = Arc::from(s);
+}
+
+#[test]
+fn test_from_box() {
+    let b: Box<u32> = box 123;
+    let r: Arc<u32> = Arc::from(b);
+
+    assert_eq!(*r, 123);
+}
+
+#[test]
+fn test_from_box_str() {
+    use std::string::String;
+
+    let s = String::from("foo").into_boxed_str();
+    let r: Arc<str> = Arc::from(s);
+
+    assert_eq!(&r[..], "foo");
+}
+
+#[test]
+fn test_from_box_slice() {
+    let s = vec![1, 2, 3].into_boxed_slice();
+    let r: Arc<[u32]> = Arc::from(s);
+
+    assert_eq!(&r[..], [1, 2, 3]);
+}
+
+#[test]
+fn test_from_box_trait() {
+    use std::fmt::Display;
+    use std::string::ToString;
+
+    let b: Box<dyn Display> = box 123;
+    let r: Arc<dyn Display> = Arc::from(b);
+
+    assert_eq!(r.to_string(), "123");
+}
+
+#[test]
+fn test_from_box_trait_zero_sized() {
+    use std::fmt::Debug;
+
+    let b: Box<dyn Debug> = box ();
+    let r: Arc<dyn Debug> = Arc::from(b);
+
+    assert_eq!(format!("{:?}", r), "()");
+}
+
+#[test]
+fn test_from_vec() {
+    let v = vec![1, 2, 3];
+    let r: Arc<[u32]> = Arc::from(v);
+
+    assert_eq!(&r[..], [1, 2, 3]);
+}
+
+#[test]
+fn test_downcast() {
+    use std::any::Any;
+
+    let r1: Arc<dyn Any + Send + Sync> = Arc::new(i32::max_value());
+    let r2: Arc<dyn Any + Send + Sync> = Arc::new("abc");
+
+    assert!(r1.clone().downcast::<u32>().is_err());
+
+    let r1i32 = r1.downcast::<i32>();
+    assert!(r1i32.is_ok());
+    assert_eq!(r1i32.unwrap(), Arc::new(i32::max_value()));
+
+    assert!(r2.clone().downcast::<i32>().is_err());
+
+    let r2str = r2.downcast::<&'static str>();
+    assert!(r2str.is_ok());
+    assert_eq!(r2str.unwrap(), Arc::new("abc"));
+}
diff --git a/src/tools/tidy/src/unit_tests.rs b/src/tools/tidy/src/unit_tests.rs
index d01069f4269..6286945ad26 100644
--- a/src/tools/tidy/src/unit_tests.rs
+++ b/src/tools/tidy/src/unit_tests.rs
@@ -1,11 +1,9 @@
-//! Tidy check to ensure `#[test]` and `#[bench]` are not used directly inside
-//! `libcore` or `liballoc`.
+//! Tidy check to ensure `#[test]` and `#[bench]` are not used directly inside `libcore`.
 //!
-//! `#![no_std]` libraries cannot be tested directly due to duplicating lang
-//! items. All tests and benchmarks must be written externally in `libcore/{tests,benches}`
-//! or `liballoc/{tests,benches}`.
+//! `#![no_core]` libraries cannot be tested directly due to duplicating lang
+//! items. All tests and benchmarks must be written externally in `libcore/{tests,benches}`.
 //!
-//! Outside of libcore and liballoc tests and benchmarks should be outlined into separate files
+//! Outside of libcore tests and benchmarks should be outlined into separate files
 //! named `tests.rs` or `benches.rs`, or directories named `tests` or `benches` unconfigured
 //! during normal build.
 
@@ -13,22 +11,12 @@ use std::path::Path;
 
 pub fn check(root_path: &Path, bad: &mut bool) {
     let libcore = &root_path.join("libcore");
-    let liballoc = &root_path.join("liballoc");
     let libcore_tests = &root_path.join("libcore/tests");
-    let liballoc_tests = &root_path.join("liballoc/tests");
     let libcore_benches = &root_path.join("libcore/benches");
-    let liballoc_benches = &root_path.join("liballoc/benches");
-    let is_core_or_alloc = |path: &Path| {
-        let is_core = path.starts_with(libcore) &&
-                      !(path.starts_with(libcore_tests) || path.starts_with(libcore_benches));
-        let is_alloc = path.starts_with(liballoc) &&
-                       !(path.starts_with(liballoc_tests) || path.starts_with(liballoc_benches));
-        is_core || is_alloc
+    let is_core = |path: &Path| {
+        path.starts_with(libcore) &&
+        !(path.starts_with(libcore_tests) || path.starts_with(libcore_benches))
     };
-    let fixme = [
-        "liballoc",
-        "libstd",
-    ];
 
     let mut skip = |path: &Path| {
         let file_name = path.file_name().unwrap_or_default();
@@ -36,12 +24,12 @@ pub fn check(root_path: &Path, bad: &mut bool) {
             super::filter_dirs(path) ||
             path.ends_with("src/test") ||
             path.ends_with("src/doc") ||
-            (file_name == "tests" || file_name == "benches") && !is_core_or_alloc(path) ||
-            fixme.iter().any(|p| path.ends_with(p))
+            path.ends_with("src/libstd") || // FIXME?
+            (file_name == "tests" || file_name == "benches") && !is_core(path)
         } else {
             let extension = path.extension().unwrap_or_default();
             extension != "rs" ||
-            (file_name == "tests.rs" || file_name == "benches.rs") && !is_core_or_alloc(path)
+            (file_name == "tests.rs" || file_name == "benches.rs") && !is_core(path)
         }
     };
 
@@ -51,7 +39,6 @@ pub fn check(root_path: &Path, bad: &mut bool) {
         &mut |entry, contents| {
             let path = entry.path();
             let is_libcore = path.starts_with(libcore);
-            let is_liballoc = path.starts_with(liballoc);
             for (i, line) in contents.lines().enumerate() {
                 let line = line.trim();
                 let is_test = || line.contains("#[test]") && !line.contains("`#[test]");
@@ -60,9 +47,6 @@ pub fn check(root_path: &Path, bad: &mut bool) {
                     let explanation = if is_libcore {
                         "libcore unit tests and benchmarks must be placed into \
                          `libcore/tests` or `libcore/benches`"
-                    } else if is_liballoc {
-                        "liballoc unit tests and benchmarks must be placed into \
-                         `liballoc/tests` or `liballoc/benches`"
                     } else {
                         "unit tests and benchmarks must be placed into \
                          separate files or directories named \