about summary refs log tree commit diff
path: root/tests/ui/stdlib-unit-tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/stdlib-unit-tests')
-rw-r--r--tests/ui/stdlib-unit-tests/builtin-clone.rs45
-rw-r--r--tests/ui/stdlib-unit-tests/eq-multidispatch.rs30
-rw-r--r--tests/ui/stdlib-unit-tests/issue-21058.rs64
-rw-r--r--tests/ui/stdlib-unit-tests/istr.rs53
-rw-r--r--tests/ui/stdlib-unit-tests/log-knows-the-names-of-variants-in-std.rs27
-rw-r--r--tests/ui/stdlib-unit-tests/matches2021.rs13
-rw-r--r--tests/ui/stdlib-unit-tests/minmax-stability-issue-23687.rs64
-rw-r--r--tests/ui/stdlib-unit-tests/not-sync.rs22
-rw-r--r--tests/ui/stdlib-unit-tests/not-sync.stderr81
-rw-r--r--tests/ui/stdlib-unit-tests/raw-fat-ptr.rs119
-rw-r--r--tests/ui/stdlib-unit-tests/seq-compare.rs16
-rw-r--r--tests/ui/stdlib-unit-tests/volatile-fat-ptr.rs15
12 files changed, 549 insertions, 0 deletions
diff --git a/tests/ui/stdlib-unit-tests/builtin-clone.rs b/tests/ui/stdlib-unit-tests/builtin-clone.rs
new file mode 100644
index 00000000000..0874d5bc390
--- /dev/null
+++ b/tests/ui/stdlib-unit-tests/builtin-clone.rs
@@ -0,0 +1,45 @@
+// run-pass
+// Test that `Clone` is correctly implemented for builtin types.
+// Also test that cloning an array or a tuple is done right, i.e.
+// each component is cloned.
+
+fn test_clone<T: Clone>(arg: T) {
+    let _ = arg.clone();
+}
+
+fn foo() { }
+
+#[derive(Debug, PartialEq, Eq)]
+struct S(i32);
+
+impl Clone for S {
+    fn clone(&self) -> Self {
+        S(self.0 + 1)
+    }
+}
+
+fn main() {
+    test_clone(foo);
+    test_clone([1; 56]);
+    test_clone((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1));
+
+    let a = [S(0), S(1), S(2)];
+    let b = [S(1), S(2), S(3)];
+    assert_eq!(b, a.clone());
+
+    let a = (
+        (S(1), S(0)),
+        (
+            (S(0), S(0), S(1)),
+            S(0)
+        )
+    );
+    let b = (
+        (S(2), S(1)),
+        (
+            (S(1), S(1), S(2)),
+            S(1)
+        )
+    );
+    assert_eq!(b, a.clone());
+}
diff --git a/tests/ui/stdlib-unit-tests/eq-multidispatch.rs b/tests/ui/stdlib-unit-tests/eq-multidispatch.rs
new file mode 100644
index 00000000000..69d83f496b3
--- /dev/null
+++ b/tests/ui/stdlib-unit-tests/eq-multidispatch.rs
@@ -0,0 +1,30 @@
+// run-pass
+
+#[derive(PartialEq, Debug)]
+struct Bar;
+#[derive(Debug)]
+struct Baz;
+#[derive(Debug)]
+struct Foo;
+#[derive(Debug)]
+struct Fu;
+
+impl PartialEq for Baz { fn eq(&self, _: &Baz) -> bool  { true } }
+
+impl PartialEq<Fu> for Foo { fn eq(&self, _: &Fu) -> bool { true } }
+impl PartialEq<Foo> for Fu { fn eq(&self, _: &Foo) -> bool { true } }
+
+impl PartialEq<Bar> for Foo { fn eq(&self, _: &Bar) -> bool { false } }
+impl PartialEq<Foo> for Bar { fn eq(&self, _: &Foo) -> bool { false } }
+
+fn main() {
+    assert!(Bar != Foo);
+    assert!(Foo != Bar);
+
+    assert_eq!(Bar, Bar);
+
+    assert_eq!(Baz, Baz);
+
+    assert_eq!(Foo, Fu);
+    assert_eq!(Fu, Foo);
+}
diff --git a/tests/ui/stdlib-unit-tests/issue-21058.rs b/tests/ui/stdlib-unit-tests/issue-21058.rs
new file mode 100644
index 00000000000..6facf0b2dd5
--- /dev/null
+++ b/tests/ui/stdlib-unit-tests/issue-21058.rs
@@ -0,0 +1,64 @@
+// run-pass
+#![allow(dead_code)]
+
+use std::fmt::Debug;
+
+struct NT(str);
+struct DST { a: u32, b: str }
+
+macro_rules! check {
+    (val: $ty_of:expr, $expected:expr) => {
+        assert_eq!(type_name_of_val($ty_of), $expected);
+    };
+    ($ty:ty, $expected:expr) => {
+        assert_eq!(std::any::type_name::<$ty>(), $expected);
+    };
+}
+
+fn main() {
+    // type_name should support unsized types
+    check!([u8], "[u8]");
+    check!(str, "str");
+    check!(dyn Send, "dyn core::marker::Send");
+    check!(NT, "issue_21058::NT");
+    check!(DST, "issue_21058::DST");
+    check!(&i32, "&i32");
+    check!(&'static i32, "&i32");
+    check!((i32, u32), "(i32, u32)");
+    check!(val: foo(), "issue_21058::Foo");
+    check!(val: Foo::new, "issue_21058::Foo::new");
+    check!(val:
+        <Foo as Debug>::fmt,
+        "<issue_21058::Foo as core::fmt::Debug>::fmt"
+    );
+    check!(val: || {}, "issue_21058::main::{{closure}}");
+    bar::<i32>();
+}
+
+trait Trait {
+    type Assoc;
+}
+
+impl Trait for i32 {
+    type Assoc = String;
+}
+
+fn bar<T: Trait>() {
+    check!(T::Assoc, "alloc::string::String");
+    check!(T, "i32");
+}
+
+fn type_name_of_val<T>(_: T) -> &'static str {
+    std::any::type_name::<T>()
+}
+
+#[derive(Debug)]
+struct Foo;
+
+impl Foo {
+    fn new() -> Self { Foo }
+}
+
+fn foo() -> impl Debug {
+    Foo
+}
diff --git a/tests/ui/stdlib-unit-tests/istr.rs b/tests/ui/stdlib-unit-tests/istr.rs
new file mode 100644
index 00000000000..dca6d40d59a
--- /dev/null
+++ b/tests/ui/stdlib-unit-tests/istr.rs
@@ -0,0 +1,53 @@
+// run-pass
+
+use std::string::String;
+
+fn test_stack_assign() {
+    let s: String = "a".to_string();
+    println!("{}", s.clone());
+    let t: String = "a".to_string();
+    assert_eq!(s, t);
+    let u: String = "b".to_string();
+    assert!((s != u));
+}
+
+fn test_heap_lit() { "a big string".to_string(); }
+
+fn test_heap_assign() {
+    let s: String = "a big ol' string".to_string();
+    let t: String = "a big ol' string".to_string();
+    assert_eq!(s, t);
+    let u: String = "a bad ol' string".to_string();
+    assert!((s != u));
+}
+
+fn test_heap_log() {
+    let s = "a big ol' string".to_string();
+    println!("{}", s);
+}
+
+fn test_append() {
+    let mut s = String::new();
+    s.push_str("a");
+    assert_eq!(s, "a");
+
+    let mut s = String::from("a");
+    s.push_str("b");
+    println!("{}", s.clone());
+    assert_eq!(s, "ab");
+
+    let mut s = String::from("c");
+    s.push_str("offee");
+    assert_eq!(s, "coffee");
+
+    s.push_str("&tea");
+    assert_eq!(s, "coffee&tea");
+}
+
+pub fn main() {
+    test_stack_assign();
+    test_heap_lit();
+    test_heap_assign();
+    test_heap_log();
+    test_append();
+}
diff --git a/tests/ui/stdlib-unit-tests/log-knows-the-names-of-variants-in-std.rs b/tests/ui/stdlib-unit-tests/log-knows-the-names-of-variants-in-std.rs
new file mode 100644
index 00000000000..c5a40edbeef
--- /dev/null
+++ b/tests/ui/stdlib-unit-tests/log-knows-the-names-of-variants-in-std.rs
@@ -0,0 +1,27 @@
+// run-pass
+
+#![allow(non_camel_case_types)]
+#![allow(dead_code)]
+#[derive(Clone, Debug)]
+enum foo {
+  a(usize),
+  b(String),
+}
+
+fn check_log<T: std::fmt::Debug>(exp: String, v: T) {
+    assert_eq!(exp, format!("{:?}", v));
+}
+
+pub fn main() {
+    let mut x = Some(foo::a(22));
+    let exp = "Some(a(22))".to_string();
+    let act = format!("{:?}", x);
+    assert_eq!(act, exp);
+    check_log(exp, x);
+
+    x = None;
+    let exp = "None".to_string();
+    let act = format!("{:?}", x);
+    assert_eq!(act, exp);
+    check_log(exp, x);
+}
diff --git a/tests/ui/stdlib-unit-tests/matches2021.rs b/tests/ui/stdlib-unit-tests/matches2021.rs
new file mode 100644
index 00000000000..9143a8cdd59
--- /dev/null
+++ b/tests/ui/stdlib-unit-tests/matches2021.rs
@@ -0,0 +1,13 @@
+// run-pass
+// edition:2021
+
+// regression test for https://github.com/rust-lang/rust/pull/85678
+
+#![feature(assert_matches)]
+
+use std::assert_matches::assert_matches;
+
+fn main() {
+    assert!(matches!((), ()));
+    assert_matches!((), ());
+}
diff --git a/tests/ui/stdlib-unit-tests/minmax-stability-issue-23687.rs b/tests/ui/stdlib-unit-tests/minmax-stability-issue-23687.rs
new file mode 100644
index 00000000000..9100bfbde95
--- /dev/null
+++ b/tests/ui/stdlib-unit-tests/minmax-stability-issue-23687.rs
@@ -0,0 +1,64 @@
+// run-pass
+
+use std::fmt::Debug;
+use std::cmp::{self, PartialOrd, Ordering};
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+struct Foo {
+    n: u8,
+    name: &'static str
+}
+
+impl PartialOrd for Foo {
+    fn partial_cmp(&self, other: &Foo) -> Option<Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl Ord for Foo {
+    fn cmp(&self, other: &Foo) -> Ordering {
+        self.n.cmp(&other.n)
+    }
+}
+
+fn main() {
+    let a = Foo { n: 4, name: "a" };
+    let b = Foo { n: 4, name: "b" };
+    let c = Foo { n: 8, name: "c" };
+    let d = Foo { n: 8, name: "d" };
+    let e = Foo { n: 22, name: "e" };
+    let f = Foo { n: 22, name: "f" };
+
+    let data = [a, b, c, d, e, f];
+
+    // `min` should return the left when the values are equal
+    assert_eq!(data.iter().min(), Some(&a));
+    assert_eq!(data.iter().min_by_key(|a| a.n), Some(&a));
+    assert_eq!(cmp::min(a, b), a);
+    assert_eq!(cmp::min(b, a), b);
+
+    // `max` should return the right when the values are equal
+    assert_eq!(data.iter().max(), Some(&f));
+    assert_eq!(data.iter().max_by_key(|a| a.n), Some(&f));
+    assert_eq!(cmp::max(e, f), f);
+    assert_eq!(cmp::max(f, e), e);
+
+    let mut presorted = data.to_vec();
+    presorted.sort();
+    assert_stable(&presorted);
+
+    let mut presorted = data.to_vec();
+    presorted.sort_by(|a, b| a.cmp(b));
+    assert_stable(&presorted);
+
+    // Assert that sorted and min/max are the same
+    fn assert_stable<T: Ord + Debug>(presorted: &[T]) {
+        for slice in presorted.windows(2) {
+            let a = &slice[0];
+            let b = &slice[1];
+
+            assert_eq!(a, cmp::min(a, b));
+            assert_eq!(b, cmp::max(a, b));
+        }
+    }
+}
diff --git a/tests/ui/stdlib-unit-tests/not-sync.rs b/tests/ui/stdlib-unit-tests/not-sync.rs
new file mode 100644
index 00000000000..f4648994fa9
--- /dev/null
+++ b/tests/ui/stdlib-unit-tests/not-sync.rs
@@ -0,0 +1,22 @@
+use std::cell::{Cell, RefCell};
+use std::rc::{Rc, Weak};
+use std::sync::mpsc::{Receiver, Sender};
+
+fn test<T: Sync>() {}
+
+fn main() {
+    test::<Cell<i32>>();
+    //~^ ERROR `Cell<i32>` cannot be shared between threads safely [E0277]
+    test::<RefCell<i32>>();
+    //~^ ERROR `RefCell<i32>` cannot be shared between threads safely [E0277]
+
+    test::<Rc<i32>>();
+    //~^ ERROR `Rc<i32>` cannot be shared between threads safely [E0277]
+    test::<Weak<i32>>();
+    //~^ ERROR `std::rc::Weak<i32>` cannot be shared between threads safely [E0277]
+
+    test::<Receiver<i32>>();
+    //~^ ERROR `std::sync::mpsc::Receiver<i32>` cannot be shared between threads safely [E0277]
+    test::<Sender<i32>>();
+    //~^ ERROR `Sender<i32>` cannot be shared between threads safely [E0277]
+}
diff --git a/tests/ui/stdlib-unit-tests/not-sync.stderr b/tests/ui/stdlib-unit-tests/not-sync.stderr
new file mode 100644
index 00000000000..1ee358ba836
--- /dev/null
+++ b/tests/ui/stdlib-unit-tests/not-sync.stderr
@@ -0,0 +1,81 @@
+error[E0277]: `Cell<i32>` cannot be shared between threads safely
+  --> $DIR/not-sync.rs:8:12
+   |
+LL |     test::<Cell<i32>>();
+   |            ^^^^^^^^^ `Cell<i32>` cannot be shared between threads safely
+   |
+   = help: the trait `Sync` is not implemented for `Cell<i32>`
+note: required by a bound in `test`
+  --> $DIR/not-sync.rs:5:12
+   |
+LL | fn test<T: Sync>() {}
+   |            ^^^^ required by this bound in `test`
+
+error[E0277]: `RefCell<i32>` cannot be shared between threads safely
+  --> $DIR/not-sync.rs:10:12
+   |
+LL |     test::<RefCell<i32>>();
+   |            ^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
+   |
+   = help: the trait `Sync` is not implemented for `RefCell<i32>`
+note: required by a bound in `test`
+  --> $DIR/not-sync.rs:5:12
+   |
+LL | fn test<T: Sync>() {}
+   |            ^^^^ required by this bound in `test`
+
+error[E0277]: `Rc<i32>` cannot be shared between threads safely
+  --> $DIR/not-sync.rs:13:12
+   |
+LL |     test::<Rc<i32>>();
+   |            ^^^^^^^ `Rc<i32>` cannot be shared between threads safely
+   |
+   = help: the trait `Sync` is not implemented for `Rc<i32>`
+note: required by a bound in `test`
+  --> $DIR/not-sync.rs:5:12
+   |
+LL | fn test<T: Sync>() {}
+   |            ^^^^ required by this bound in `test`
+
+error[E0277]: `std::rc::Weak<i32>` cannot be shared between threads safely
+  --> $DIR/not-sync.rs:15:12
+   |
+LL |     test::<Weak<i32>>();
+   |            ^^^^^^^^^ `std::rc::Weak<i32>` cannot be shared between threads safely
+   |
+   = help: the trait `Sync` is not implemented for `std::rc::Weak<i32>`
+note: required by a bound in `test`
+  --> $DIR/not-sync.rs:5:12
+   |
+LL | fn test<T: Sync>() {}
+   |            ^^^^ required by this bound in `test`
+
+error[E0277]: `std::sync::mpsc::Receiver<i32>` cannot be shared between threads safely
+  --> $DIR/not-sync.rs:18:12
+   |
+LL |     test::<Receiver<i32>>();
+   |            ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<i32>` cannot be shared between threads safely
+   |
+   = help: the trait `Sync` is not implemented for `std::sync::mpsc::Receiver<i32>`
+note: required by a bound in `test`
+  --> $DIR/not-sync.rs:5:12
+   |
+LL | fn test<T: Sync>() {}
+   |            ^^^^ required by this bound in `test`
+
+error[E0277]: `Sender<i32>` cannot be shared between threads safely
+  --> $DIR/not-sync.rs:20:12
+   |
+LL |     test::<Sender<i32>>();
+   |            ^^^^^^^^^^^ `Sender<i32>` cannot be shared between threads safely
+   |
+   = help: the trait `Sync` is not implemented for `Sender<i32>`
+note: required by a bound in `test`
+  --> $DIR/not-sync.rs:5:12
+   |
+LL | fn test<T: Sync>() {}
+   |            ^^^^ required by this bound in `test`
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/stdlib-unit-tests/raw-fat-ptr.rs b/tests/ui/stdlib-unit-tests/raw-fat-ptr.rs
new file mode 100644
index 00000000000..6b0b09c9894
--- /dev/null
+++ b/tests/ui/stdlib-unit-tests/raw-fat-ptr.rs
@@ -0,0 +1,119 @@
+// run-pass
+// check raw fat pointer ops
+
+use std::mem;
+
+fn assert_inorder<T: PartialEq + PartialOrd>(a: &[T]) {
+    for i in 0..a.len() {
+        for j in 0..a.len() {
+            if i < j {
+                assert!(a[i] < a[j]);
+                assert!(a[i] <= a[j]);
+                assert!(!(a[i] == a[j]));
+                assert!(a[i] != a[j]);
+                assert!(!(a[i] >= a[j]));
+                assert!(!(a[i] > a[j]));
+            } else if i == j {
+                assert!(!(a[i] < a[j]));
+                assert!(a[i] <= a[j]);
+                assert!(a[i] == a[j]);
+                assert!(!(a[i] != a[j]));
+                assert!(a[i] >= a[j]);
+                assert!(!(a[i] > a[j]));
+            } else {
+                assert!(!(a[i] < a[j]));
+                assert!(!(a[i] <= a[j]));
+                assert!(!(a[i] == a[j]));
+                assert!(a[i] != a[j]);
+                assert!(a[i] >= a[j]);
+                assert!(a[i] > a[j]);
+            }
+        }
+    }
+}
+
+trait Foo { fn foo(&self) -> usize; }
+impl<T> Foo for T {
+    fn foo(&self) -> usize {
+        mem::size_of::<T>()
+    }
+}
+
+#[allow(unused_tuple_struct_fields)]
+struct S<T:?Sized>(u32, T);
+
+fn main() {
+    let mut array = [0,1,2,3,4];
+    let mut array2 = [5,6,7,8,9];
+
+    // fat ptr comparison: addr then extra
+
+    // check ordering for arrays
+    let mut ptrs: Vec<*const [u8]> = vec![
+        &array[0..0], &array[0..1], &array, &array[1..]
+    ];
+
+    let array_addr = &array as *const [u8] as *const u8 as usize;
+    let array2_addr = &array2 as *const [u8] as *const u8 as usize;
+    if array2_addr < array_addr {
+        ptrs.insert(0, &array2);
+    } else {
+        ptrs.push(&array2);
+    }
+    assert_inorder(&ptrs);
+
+    // check ordering for mut arrays
+    let mut ptrs: Vec<*mut [u8]> = vec![
+        &mut array[0..0], &mut array[0..1], &mut array, &mut array[1..]
+    ];
+
+    let array_addr = &mut array as *mut [u8] as *mut u8 as usize;
+    let array2_addr = &mut array2 as *mut [u8] as *mut u8 as usize;
+    if array2_addr < array_addr {
+        ptrs.insert(0, &mut array2);
+    } else {
+        ptrs.push(&mut array2);
+    }
+    assert_inorder(&ptrs);
+
+    let mut u8_ = (0u8, 1u8);
+    let mut u32_ = (4u32, 5u32);
+
+    // check ordering for ptrs
+    let buf: &mut [*const dyn Foo] = &mut [
+        &u8_, &u8_.0,
+        &u32_, &u32_.0,
+    ];
+    buf.sort_by(|u,v| {
+        let u : [*const (); 2] = unsafe { mem::transmute(*u) };
+        let v : [*const (); 2] = unsafe { mem::transmute(*v) };
+        u.cmp(&v)
+    });
+    assert_inorder(buf);
+
+    // check ordering for mut ptrs
+    let buf: &mut [*mut dyn Foo] = &mut [
+        &mut u8_, &mut u8_.0,
+        &mut u32_, &mut u32_.0,
+    ];
+    buf.sort_by(|u,v| {
+        let u : [*const (); 2] = unsafe { mem::transmute(*u) };
+        let v : [*const (); 2] = unsafe { mem::transmute(*v) };
+        u.cmp(&v)
+    });
+    assert_inorder(buf);
+
+    // check ordering for structs containing arrays
+    let ss: (S<[u8; 2]>,
+             S<[u8; 3]>,
+             S<[u8; 2]>) = (
+        S(7, [8, 9]),
+        S(10, [11, 12, 13]),
+        S(4, [5, 6])
+    );
+    assert_inorder(&[
+        &ss.0 as *const S<[u8]>,
+        &ss.1 as *const S<[u8]>,
+        &ss.2 as *const S<[u8]>
+    ]);
+}
diff --git a/tests/ui/stdlib-unit-tests/seq-compare.rs b/tests/ui/stdlib-unit-tests/seq-compare.rs
new file mode 100644
index 00000000000..4078326b559
--- /dev/null
+++ b/tests/ui/stdlib-unit-tests/seq-compare.rs
@@ -0,0 +1,16 @@
+// run-pass
+
+pub fn main() {
+    assert!(("hello".to_string() < "hellr".to_string()));
+    assert!(("hello ".to_string() > "hello".to_string()));
+    assert!(("hello".to_string() != "there".to_string()));
+    assert!((vec![1, 2, 3, 4] > vec![1, 2, 3]));
+    assert!((vec![1, 2, 3] < vec![1, 2, 3, 4]));
+    assert!((vec![1, 2, 4, 4] > vec![1, 2, 3, 4]));
+    assert!((vec![1, 2, 3, 4] < vec![1, 2, 4, 4]));
+    assert!((vec![1, 2, 3] <= vec![1, 2, 3]));
+    assert!((vec![1, 2, 3] <= vec![1, 2, 3, 3]));
+    assert!((vec![1, 2, 3, 4] > vec![1, 2, 3]));
+    assert_eq!(vec![1, 2, 3], vec![1, 2, 3]);
+    assert!((vec![1, 2, 3] != vec![1, 1, 3]));
+}
diff --git a/tests/ui/stdlib-unit-tests/volatile-fat-ptr.rs b/tests/ui/stdlib-unit-tests/volatile-fat-ptr.rs
new file mode 100644
index 00000000000..f73e7e1c391
--- /dev/null
+++ b/tests/ui/stdlib-unit-tests/volatile-fat-ptr.rs
@@ -0,0 +1,15 @@
+// run-pass
+
+#![allow(stable_features)]
+#![feature(volatile)]
+use std::ptr::{read_volatile, write_volatile};
+
+fn main() {
+    let mut x: &'static str = "test";
+    unsafe {
+        let a = read_volatile(&x);
+        assert_eq!(a, "test");
+        write_volatile(&mut x, "foo");
+        assert_eq!(x, "foo");
+    }
+}