summaryrefslogtreecommitdiffstats
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 000000000..0874d5bc3
--- /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 000000000..69d83f496
--- /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 000000000..6facf0b2d
--- /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 000000000..dca6d40d5
--- /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 000000000..c5a40edbe
--- /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 000000000..9143a8cdd
--- /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 000000000..9100bfbde
--- /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 000000000..f4648994f
--- /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 000000000..1ee358ba8
--- /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 000000000..6b0b09c98
--- /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 000000000..4078326b5
--- /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 000000000..f73e7e1c3
--- /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");
+ }
+}