diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2019-07-27 01:33:01 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2019-07-27 18:56:16 +0300 |
| commit | 9be35f82c1abf2ecbab489bca9eca138ea648312 (patch) | |
| tree | 69888506e34af447d9748c0d542de3ba1dd76210 /src/test/ui/coerce | |
| parent | ca9faa52f5ada0054b1fa27d97aedf448afb059b (diff) | |
| download | rust-9be35f82c1abf2ecbab489bca9eca138ea648312.tar.gz rust-9be35f82c1abf2ecbab489bca9eca138ea648312.zip | |
tests: Move run-pass tests without naming conflicts to ui
Diffstat (limited to 'src/test/ui/coerce')
| -rw-r--r-- | src/test/ui/coerce/coerce-expect-unsized.rs | 43 | ||||
| -rw-r--r-- | src/test/ui/coerce/coerce-overloaded-autoderef.rs | 67 | ||||
| -rw-r--r-- | src/test/ui/coerce/coerce-reborrow-imm-ptr-arg.rs | 17 | ||||
| -rw-r--r-- | src/test/ui/coerce/coerce-reborrow-imm-ptr-rcvr.rs | 18 | ||||
| -rw-r--r-- | src/test/ui/coerce/coerce-reborrow-imm-vec-arg.rs | 19 | ||||
| -rw-r--r-- | src/test/ui/coerce/coerce-reborrow-imm-vec-rcvr.rs | 16 | ||||
| -rw-r--r-- | src/test/ui/coerce/coerce-reborrow-mut-ptr-arg.rs | 25 | ||||
| -rw-r--r-- | src/test/ui/coerce/coerce-reborrow-mut-ptr-rcvr.rs | 27 | ||||
| -rw-r--r-- | src/test/ui/coerce/coerce-reborrow-mut-vec-arg.rs | 18 | ||||
| -rw-r--r-- | src/test/ui/coerce/coerce-reborrow-mut-vec-rcvr.rs | 14 | ||||
| -rw-r--r-- | src/test/ui/coerce/coerce-unify-return.rs | 19 | ||||
| -rw-r--r-- | src/test/ui/coerce/coerce-unify.rs | 68 | ||||
| -rw-r--r-- | src/test/ui/coerce/coerce-unsize-subtype.rs | 40 |
13 files changed, 391 insertions, 0 deletions
diff --git a/src/test/ui/coerce/coerce-expect-unsized.rs b/src/test/ui/coerce/coerce-expect-unsized.rs new file mode 100644 index 00000000000..b44aa6ab377 --- /dev/null +++ b/src/test/ui/coerce/coerce-expect-unsized.rs @@ -0,0 +1,43 @@ +// run-pass +#![feature(box_syntax)] + +use std::cell::RefCell; +use std::fmt::Debug; +use std::rc::Rc; + +// Check that coercions apply at the pointer level and don't cause +// rvalue expressions to be unsized. See #20169 for more information. + +pub fn main() { + let _: Box<[isize]> = Box::new({ [1, 2, 3] }); + let _: Box<[isize]> = Box::new(if true { [1, 2, 3] } else { [1, 3, 4] }); + let _: Box<[isize]> = Box::new(match true { true => [1, 2, 3], false => [1, 3, 4] }); + let _: Box<dyn Fn(isize) -> _> = Box::new({ |x| (x as u8) }); + let _: Box<dyn Debug> = Box::new(if true { false } else { true }); + let _: Box<dyn Debug> = Box::new(match true { true => 'a', false => 'b' }); + + let _: &[isize] = &{ [1, 2, 3] }; + let _: &[isize] = &if true { [1, 2, 3] } else { [1, 3, 4] }; + let _: &[isize] = &match true { true => [1, 2, 3], false => [1, 3, 4] }; + let _: &dyn Fn(isize) -> _ = &{ |x| (x as u8) }; + let _: &dyn Debug = &if true { false } else { true }; + let _: &dyn Debug = &match true { true => 'a', false => 'b' }; + + let _: &str = &{ String::new() }; + let _: &str = &if true { String::from("...") } else { 5.to_string() }; + let _: &str = &match true { + true => format!("{}", false), + false => ["x", "y"].join("+") + }; + + let _: Box<[isize]> = Box::new([1, 2, 3]); + let _: Box<dyn Fn(isize) -> _> = Box::new(|x| (x as u8)); + + let _: Rc<RefCell<[isize]>> = Rc::new(RefCell::new([1, 2, 3])); + let _: Rc<RefCell<dyn FnMut(isize) -> _>> = Rc::new(RefCell::new(|x| (x as u8))); + + let _: Vec<Box<dyn Fn(isize) -> _>> = vec![ + Box::new(|x| (x as u8)), + Box::new(|x| (x as i16 as u8)), + ]; +} diff --git a/src/test/ui/coerce/coerce-overloaded-autoderef.rs b/src/test/ui/coerce/coerce-overloaded-autoderef.rs new file mode 100644 index 00000000000..3fe18103ef8 --- /dev/null +++ b/src/test/ui/coerce/coerce-overloaded-autoderef.rs @@ -0,0 +1,67 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +use std::rc::Rc; + +// Examples from the "deref coercions" RFC, at rust-lang/rfcs#241. + +fn use_ref<T>(_: &T) {} +fn use_mut<T>(_: &mut T) {} + +fn use_rc<T>(t: Rc<T>) { + use_ref(&*t); // what you have to write today + use_ref(&t); // what you'd be able to write + use_ref(&&&&&&t); + use_ref(&mut &&&&&t); + use_ref(&&&mut &&&t); +} + +fn use_mut_box<T>(mut t: &mut Box<T>) { + use_mut(&mut *t); // what you have to write today + use_mut(t); // what you'd be able to write + use_mut(&mut &mut &mut t); + + use_ref(&*t); // what you have to write today + use_ref(t); // what you'd be able to write + use_ref(&&&&&&t); + use_ref(&mut &&&&&t); + use_ref(&&&mut &&&t); +} + +fn use_nested<T>(t: &Box<T>) { + use_ref(&**t); // what you have to write today + use_ref(t); // what you'd be able to write (note: recursive deref) + use_ref(&&&&&&t); + use_ref(&mut &&&&&t); + use_ref(&&&mut &&&t); +} + +fn use_slice(_: &[u8]) {} +fn use_slice_mut(_: &mut [u8]) {} + +fn use_vec(mut v: Vec<u8>) { + use_slice_mut(&mut v[..]); // what you have to write today + use_slice_mut(&mut v); // what you'd be able to write + use_slice_mut(&mut &mut &mut v); + + use_slice(&v[..]); // what you have to write today + use_slice(&v); // what you'd be able to write + use_slice(&&&&&&v); + use_slice(&mut &&&&&v); + use_slice(&&&mut &&&v); +} + +fn use_vec_ref(v: &Vec<u8>) { + use_slice(&v[..]); // what you have to write today + use_slice(v); // what you'd be able to write + use_slice(&&&&&&v); + use_slice(&mut &&&&&v); + use_slice(&&&mut &&&v); +} + +fn use_op_rhs(s: &mut String) { + *s += {&String::from(" ")}; +} + +pub fn main() {} diff --git a/src/test/ui/coerce/coerce-reborrow-imm-ptr-arg.rs b/src/test/ui/coerce/coerce-reborrow-imm-ptr-arg.rs new file mode 100644 index 00000000000..f033e1b5d2b --- /dev/null +++ b/src/test/ui/coerce/coerce-reborrow-imm-ptr-arg.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +fn negate(x: &isize) -> isize { + -*x +} + +fn negate_mut(y: &mut isize) -> isize { + negate(y) +} + +fn negate_imm(y: &isize) -> isize { + negate(y) +} + +pub fn main() {} diff --git a/src/test/ui/coerce/coerce-reborrow-imm-ptr-rcvr.rs b/src/test/ui/coerce/coerce-reborrow-imm-ptr-rcvr.rs new file mode 100644 index 00000000000..64a365229cb --- /dev/null +++ b/src/test/ui/coerce/coerce-reborrow-imm-ptr-rcvr.rs @@ -0,0 +1,18 @@ +// run-pass + +struct SpeechMaker { + speeches: usize +} + +impl SpeechMaker { + pub fn how_many(&self) -> usize { self.speeches } +} + +fn foo(speaker: &SpeechMaker) -> usize { + speaker.how_many() + 33 +} + +pub fn main() { + let lincoln = SpeechMaker {speeches: 22}; + assert_eq!(foo(&lincoln), 55); +} diff --git a/src/test/ui/coerce/coerce-reborrow-imm-vec-arg.rs b/src/test/ui/coerce/coerce-reborrow-imm-vec-arg.rs new file mode 100644 index 00000000000..c2aaae1c73e --- /dev/null +++ b/src/test/ui/coerce/coerce-reborrow-imm-vec-arg.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +fn sum(x: &[isize]) -> isize { + let mut sum = 0; + for y in x { sum += *y; } + return sum; +} + +fn sum_mut(y: &mut [isize]) -> isize { + sum(y) +} + +fn sum_imm(y: &[isize]) -> isize { + sum(y) +} + +pub fn main() {} diff --git a/src/test/ui/coerce/coerce-reborrow-imm-vec-rcvr.rs b/src/test/ui/coerce/coerce-reborrow-imm-vec-rcvr.rs new file mode 100644 index 00000000000..9a5652acf87 --- /dev/null +++ b/src/test/ui/coerce/coerce-reborrow-imm-vec-rcvr.rs @@ -0,0 +1,16 @@ +// run-pass + + +fn bar(v: &mut [usize]) -> Vec<usize> { + v.to_vec() +} + +fn bip(v: &[usize]) -> Vec<usize> { + v.to_vec() +} + +pub fn main() { + let mut the_vec = vec![1, 2, 3, 100]; + assert_eq!(the_vec.clone(), bar(&mut the_vec)); + assert_eq!(the_vec.clone(), bip(&the_vec)); +} diff --git a/src/test/ui/coerce/coerce-reborrow-mut-ptr-arg.rs b/src/test/ui/coerce/coerce-reborrow-mut-ptr-arg.rs new file mode 100644 index 00000000000..76cd6793b3c --- /dev/null +++ b/src/test/ui/coerce/coerce-reborrow-mut-ptr-arg.rs @@ -0,0 +1,25 @@ +// run-pass +// pretty-expanded FIXME #23616 + +struct SpeechMaker { + speeches: usize +} + +fn talk(x: &mut SpeechMaker) { + x.speeches += 1; +} + +fn give_a_few_speeches(speaker: &mut SpeechMaker) { + + // Here speaker is reborrowed for each call, so we don't get errors + // about speaker being moved. + + talk(speaker); + talk(speaker); + talk(speaker); +} + +pub fn main() { + let mut lincoln = SpeechMaker {speeches: 22}; + give_a_few_speeches(&mut lincoln); +} diff --git a/src/test/ui/coerce/coerce-reborrow-mut-ptr-rcvr.rs b/src/test/ui/coerce/coerce-reborrow-mut-ptr-rcvr.rs new file mode 100644 index 00000000000..e6e7c3a51aa --- /dev/null +++ b/src/test/ui/coerce/coerce-reborrow-mut-ptr-rcvr.rs @@ -0,0 +1,27 @@ +// run-pass +// pretty-expanded FIXME #23616 + +struct SpeechMaker { + speeches: usize +} + +impl SpeechMaker { + pub fn talk(&mut self) { + self.speeches += 1; + } +} + +fn give_a_few_speeches(speaker: &mut SpeechMaker) { + + // Here speaker is reborrowed for each call, so we don't get errors + // about speaker being moved. + + speaker.talk(); + speaker.talk(); + speaker.talk(); +} + +pub fn main() { + let mut lincoln = SpeechMaker {speeches: 22}; + give_a_few_speeches(&mut lincoln); +} diff --git a/src/test/ui/coerce/coerce-reborrow-mut-vec-arg.rs b/src/test/ui/coerce/coerce-reborrow-mut-vec-arg.rs new file mode 100644 index 00000000000..2635754f14d --- /dev/null +++ b/src/test/ui/coerce/coerce-reborrow-mut-vec-arg.rs @@ -0,0 +1,18 @@ +// run-pass + + +fn reverse(v: &mut [usize]) { + v.reverse(); +} + +fn bar(v: &mut [usize]) { + reverse(v); + reverse(v); + reverse(v); +} + +pub fn main() { + let mut the_vec = vec![1, 2, 3, 100]; + bar(&mut the_vec); + assert_eq!(the_vec, [100, 3, 2, 1]); +} diff --git a/src/test/ui/coerce/coerce-reborrow-mut-vec-rcvr.rs b/src/test/ui/coerce/coerce-reborrow-mut-vec-rcvr.rs new file mode 100644 index 00000000000..c03336ea37a --- /dev/null +++ b/src/test/ui/coerce/coerce-reborrow-mut-vec-rcvr.rs @@ -0,0 +1,14 @@ +// run-pass + + +fn bar(v: &mut [usize]) { + v.reverse(); + v.reverse(); + v.reverse(); +} + +pub fn main() { + let mut the_vec = vec![1, 2, 3, 100]; + bar(&mut the_vec); + assert_eq!(the_vec, [100, 3, 2, 1]); +} diff --git a/src/test/ui/coerce/coerce-unify-return.rs b/src/test/ui/coerce/coerce-unify-return.rs new file mode 100644 index 00000000000..95a7ee8fe0f --- /dev/null +++ b/src/test/ui/coerce/coerce-unify-return.rs @@ -0,0 +1,19 @@ +// run-pass +// Check that coercions unify the expected return type of a polymorphic +// function call, instead of leaving the type variables as they were. + +// pretty-expanded FIXME #23616 + +struct Foo; +impl Foo { + fn foo<T>(self, x: T) -> Option<T> { Some(x) } +} + +pub fn main() { + let _: Option<fn()> = Some(main); + let _: Option<fn()> = Foo.foo(main); + + // The same two cases, with implicit type variables made explicit. + let _: Option<fn()> = Some::<_>(main); + let _: Option<fn()> = Foo.foo::<_>(main); +} diff --git a/src/test/ui/coerce/coerce-unify.rs b/src/test/ui/coerce/coerce-unify.rs new file mode 100644 index 00000000000..f1818f9bb5a --- /dev/null +++ b/src/test/ui/coerce/coerce-unify.rs @@ -0,0 +1,68 @@ +// run-pass +// Check that coercions can unify if-else, match arms and array elements. + +// Try to construct if-else chains, matches and arrays out of given expressions. +macro_rules! check { + ($last:expr $(, $rest:expr)+) => { + // Last expression comes first because of whacky ifs and matches. + let _ = $(if false { $rest })else+ else { $last }; + + let _ = match 0 { $(_ if false => $rest,)+ _ => $last }; + + let _ = [$($rest,)+ $last]; + } +} + +// Check all non-uniform cases of 2 and 3 expressions of 2 types. +macro_rules! check2 { + ($a:expr, $b:expr) => { + check!($a, $b); + check!($b, $a); + + check!($a, $a, $b); + check!($a, $b, $a); + check!($a, $b, $b); + + check!($b, $a, $a); + check!($b, $a, $b); + check!($b, $b, $a); + } +} + +// Check all non-uniform cases of 2 and 3 expressions of 3 types. +macro_rules! check3 { + ($a:expr, $b:expr, $c:expr) => { + // Delegate to check2 for cases where a type repeats. + check2!($a, $b); + check2!($b, $c); + check2!($a, $c); + + // Check the remaining cases, i.e., permutations of ($a, $b, $c). + check!($a, $b, $c); + check!($a, $c, $b); + check!($b, $a, $c); + check!($b, $c, $a); + check!($c, $a, $b); + check!($c, $b, $a); + } +} + +use std::mem::size_of; + +fn foo() {} +fn bar() {} + +pub fn main() { + check3!(foo, bar, foo as fn()); + check3!(size_of::<u8>, size_of::<u16>, size_of::<usize> as fn() -> usize); + + let s = String::from("bar"); + check2!("foo", &s); + + let a = [1, 2, 3]; + let v = vec![1, 2, 3]; + check2!(&a[..], &v); + + // Make sure in-array coercion still works. + let _ = [("a", Default::default()), (Default::default(), "b"), (&s, &s)]; +} diff --git a/src/test/ui/coerce/coerce-unsize-subtype.rs b/src/test/ui/coerce/coerce-unsize-subtype.rs new file mode 100644 index 00000000000..45b53300c5b --- /dev/null +++ b/src/test/ui/coerce/coerce-unsize-subtype.rs @@ -0,0 +1,40 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +use std::rc::Rc; + +fn lub_short<'a, T>(_: &[&'a T], _: &[&'a T]) {} + +// The two arguments are a subtype of their LUB, after coercion. +fn long_and_short<'a, T>(xs: &[&'static T; 1], ys: &[&'a T; 1]) { + lub_short(xs, ys); +} + +// The argument coerces to a subtype of the return type. +fn long_to_short<'a, 'b, T>(xs: &'b [&'static T; 1]) -> &'b [&'a T] { + xs +} + +// Rc<T> is covariant over T just like &T. +fn long_to_short_rc<'a, T>(xs: Rc<[&'static T; 1]>) -> Rc<[&'a T]> { + xs +} + +// LUB-coercion (if-else/match/array) coerces `xs: &'b [&'static T: N]` +// to a subtype of the LUB of `xs` and `ys` (i.e., `&'b [&'a T]`), +// regardless of the order they appear (in if-else/match/array). +fn long_and_short_lub1<'a, 'b, T>(xs: &'b [&'static T; 1], ys: &'b [&'a T]) { + let _order1 = [xs, ys]; + let _order2 = [ys, xs]; +} + +// LUB-coercion should also have the exact same effect when `&'b [&'a T; N]` +// needs to be coerced, i.e., the resulting type is not &'b [&'static T], but +// rather the `&'b [&'a T]` LUB. +fn long_and_short_lub2<'a, 'b, T>(xs: &'b [&'static T], ys: &'b [&'a T; 1]) { + let _order1 = [xs, ys]; + let _order2 = [ys, xs]; +} + +fn main() {} |
