diff options
Diffstat (limited to 'tests/ui/stdlib-unit-tests')
-rw-r--r-- | tests/ui/stdlib-unit-tests/builtin-clone.rs | 45 | ||||
-rw-r--r-- | tests/ui/stdlib-unit-tests/eq-multidispatch.rs | 30 | ||||
-rw-r--r-- | tests/ui/stdlib-unit-tests/issue-21058.rs | 64 | ||||
-rw-r--r-- | tests/ui/stdlib-unit-tests/istr.rs | 53 | ||||
-rw-r--r-- | tests/ui/stdlib-unit-tests/log-knows-the-names-of-variants-in-std.rs | 27 | ||||
-rw-r--r-- | tests/ui/stdlib-unit-tests/matches2021.rs | 13 | ||||
-rw-r--r-- | tests/ui/stdlib-unit-tests/minmax-stability-issue-23687.rs | 64 | ||||
-rw-r--r-- | tests/ui/stdlib-unit-tests/not-sync.rs | 22 | ||||
-rw-r--r-- | tests/ui/stdlib-unit-tests/not-sync.stderr | 81 | ||||
-rw-r--r-- | tests/ui/stdlib-unit-tests/raw-fat-ptr.rs | 119 | ||||
-rw-r--r-- | tests/ui/stdlib-unit-tests/seq-compare.rs | 16 | ||||
-rw-r--r-- | tests/ui/stdlib-unit-tests/volatile-fat-ptr.rs | 15 |
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"); + } +} |