about summary refs log tree commit diff
path: root/src/test/ui/coerce
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-07-27 01:33:01 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-07-27 18:56:16 +0300
commit9be35f82c1abf2ecbab489bca9eca138ea648312 (patch)
tree69888506e34af447d9748c0d542de3ba1dd76210 /src/test/ui/coerce
parentca9faa52f5ada0054b1fa27d97aedf448afb059b (diff)
downloadrust-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.rs43
-rw-r--r--src/test/ui/coerce/coerce-overloaded-autoderef.rs67
-rw-r--r--src/test/ui/coerce/coerce-reborrow-imm-ptr-arg.rs17
-rw-r--r--src/test/ui/coerce/coerce-reborrow-imm-ptr-rcvr.rs18
-rw-r--r--src/test/ui/coerce/coerce-reborrow-imm-vec-arg.rs19
-rw-r--r--src/test/ui/coerce/coerce-reborrow-imm-vec-rcvr.rs16
-rw-r--r--src/test/ui/coerce/coerce-reborrow-mut-ptr-arg.rs25
-rw-r--r--src/test/ui/coerce/coerce-reborrow-mut-ptr-rcvr.rs27
-rw-r--r--src/test/ui/coerce/coerce-reborrow-mut-vec-arg.rs18
-rw-r--r--src/test/ui/coerce/coerce-reborrow-mut-vec-rcvr.rs14
-rw-r--r--src/test/ui/coerce/coerce-unify-return.rs19
-rw-r--r--src/test/ui/coerce/coerce-unify.rs68
-rw-r--r--src/test/ui/coerce/coerce-unsize-subtype.rs40
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() {}