about summary refs log tree commit diff
path: root/src/test/ui/self
diff options
context:
space:
mode:
authorTaiki Endo <te316e89@gmail.com>2019-05-19 12:31:08 +0900
committerTaiki Endo <te316e89@gmail.com>2019-05-19 12:31:08 +0900
commitb53d839b239d8fcf4cddfbd565ce5a8836217d5c (patch)
tree01070625ca6a6dcc4ed210cae35b6abfeeca8548 /src/test/ui/self
parent548add7f61bfcbe3bea3f5ccefb53c84da8fefe4 (diff)
downloadrust-b53d839b239d8fcf4cddfbd565ce5a8836217d5c.tar.gz
rust-b53d839b239d8fcf4cddfbd565ce5a8836217d5c.zip
Move arbitrary_self_types's tests into ui/self
Diffstat (limited to 'src/test/ui/self')
-rw-r--r--src/test/ui/self/arbitrary-self-types-not-object-safe.rs41
-rw-r--r--src/test/ui/self/arbitrary-self-types-not-object-safe.stderr20
-rw-r--r--src/test/ui/self/arbitrary_self_types_pointers_and_wrappers.rs68
-rw-r--r--src/test/ui/self/arbitrary_self_types_raw_pointer_struct.rs28
-rw-r--r--src/test/ui/self/arbitrary_self_types_raw_pointer_trait.rs61
-rw-r--r--src/test/ui/self/arbitrary_self_types_silly.rs21
-rw-r--r--src/test/ui/self/arbitrary_self_types_stdlib_pointers.rs54
-rw-r--r--src/test/ui/self/arbitrary_self_types_struct.rs25
-rw-r--r--src/test/ui/self/arbitrary_self_types_trait.rs20
-rw-r--r--src/test/ui/self/arbitrary_self_types_unsized_struct.rs17
10 files changed, 355 insertions, 0 deletions
diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.rs b/src/test/ui/self/arbitrary-self-types-not-object-safe.rs
new file mode 100644
index 00000000000..2c1fd937a65
--- /dev/null
+++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.rs
@@ -0,0 +1,41 @@
+#![feature(arbitrary_self_types)]
+
+use std::rc::Rc;
+
+trait Foo {
+    fn foo(self: &Rc<Self>) -> usize;
+}
+
+trait Bar {
+    fn foo(self: &Rc<Self>) -> usize where Self: Sized;
+    fn bar(self: Rc<Self>) -> usize;
+}
+
+impl Foo for usize {
+    fn foo(self: &Rc<Self>) -> usize {
+        **self
+    }
+}
+
+impl Bar for usize {
+    fn foo(self: &Rc<Self>) -> usize {
+        **self
+    }
+
+    fn bar(self: Rc<Self>) -> usize {
+        *self
+    }
+}
+
+fn make_foo() {
+    let x = Rc::new(5usize) as Rc<Foo>;
+    //~^ ERROR E0038
+    //~| ERROR E0038
+}
+
+fn make_bar() {
+    let x = Rc::new(5usize) as Rc<Bar>;
+    x.bar();
+}
+
+fn main() {}
diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.stderr
new file mode 100644
index 00000000000..dacab1222ab
--- /dev/null
+++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.stderr
@@ -0,0 +1,20 @@
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/arbitrary-self-types-not-object-safe.rs:31:32
+   |
+LL |     let x = Rc::new(5usize) as Rc<Foo>;
+   |                                ^^^^^^^ the trait `Foo` cannot be made into an object
+   |
+   = note: method `foo`'s receiver cannot be dispatched on
+
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/arbitrary-self-types-not-object-safe.rs:31:13
+   |
+LL |     let x = Rc::new(5usize) as Rc<Foo>;
+   |             ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
+   |
+   = note: method `foo`'s receiver cannot be dispatched on
+   = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::rc::Rc<dyn Foo>>` for `std::rc::Rc<usize>`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/src/test/ui/self/arbitrary_self_types_pointers_and_wrappers.rs b/src/test/ui/self/arbitrary_self_types_pointers_and_wrappers.rs
new file mode 100644
index 00000000000..65fec3becac
--- /dev/null
+++ b/src/test/ui/self/arbitrary_self_types_pointers_and_wrappers.rs
@@ -0,0 +1,68 @@
+// run-pass
+#![feature(arbitrary_self_types, unsize, coerce_unsized, dispatch_from_dyn)]
+#![feature(rustc_attrs)]
+
+use std::{
+    ops::{Deref, CoerceUnsized, DispatchFromDyn},
+    marker::Unsize,
+};
+
+struct Ptr<T: ?Sized>(Box<T>);
+
+impl<T: ?Sized> Deref for Ptr<T> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        &*self.0
+    }
+}
+
+impl<T: Unsize<U> + ?Sized, U: ?Sized> CoerceUnsized<Ptr<U>> for Ptr<T> {}
+impl<T: Unsize<U> + ?Sized, U: ?Sized> DispatchFromDyn<Ptr<U>> for Ptr<T> {}
+
+struct Wrapper<T: ?Sized>(T);
+
+impl<T: ?Sized> Deref for Wrapper<T> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        &self.0
+    }
+}
+
+impl<T: CoerceUnsized<U>, U> CoerceUnsized<Wrapper<U>> for Wrapper<T> {}
+impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<Wrapper<U>> for Wrapper<T> {}
+
+
+trait Trait {
+    // This method isn't object-safe yet. Unsized by-value `self` is object-safe (but not callable
+    // without unsized_locals), but wrappers arond `Self` currently are not.
+    // FIXME (mikeyhew) uncomment this when unsized rvalues object-safety is implemented
+    // fn wrapper(self: Wrapper<Self>) -> i32;
+    fn ptr_wrapper(self: Ptr<Wrapper<Self>>) -> i32;
+    fn wrapper_ptr(self: Wrapper<Ptr<Self>>) -> i32;
+    fn wrapper_ptr_wrapper(self: Wrapper<Ptr<Wrapper<Self>>>) -> i32;
+}
+
+impl Trait for i32 {
+    fn ptr_wrapper(self: Ptr<Wrapper<Self>>) -> i32 {
+        **self
+    }
+    fn wrapper_ptr(self: Wrapper<Ptr<Self>>) -> i32 {
+        **self
+    }
+    fn wrapper_ptr_wrapper(self: Wrapper<Ptr<Wrapper<Self>>>) -> i32 {
+        ***self
+    }
+}
+
+fn main() {
+    let pw = Ptr(Box::new(Wrapper(5))) as Ptr<Wrapper<dyn Trait>>;
+    assert_eq!(pw.ptr_wrapper(), 5);
+
+    let wp = Wrapper(Ptr(Box::new(6))) as Wrapper<Ptr<dyn Trait>>;
+    assert_eq!(wp.wrapper_ptr(), 6);
+
+    let wpw = Wrapper(Ptr(Box::new(Wrapper(7)))) as Wrapper<Ptr<Wrapper<dyn Trait>>>;
+    assert_eq!(wpw.wrapper_ptr_wrapper(), 7);
+}
diff --git a/src/test/ui/self/arbitrary_self_types_raw_pointer_struct.rs b/src/test/ui/self/arbitrary_self_types_raw_pointer_struct.rs
new file mode 100644
index 00000000000..0eab7617f7a
--- /dev/null
+++ b/src/test/ui/self/arbitrary_self_types_raw_pointer_struct.rs
@@ -0,0 +1,28 @@
+// run-pass
+#![feature(arbitrary_self_types)]
+
+use std::rc::Rc;
+
+struct Foo(String);
+
+impl Foo {
+    unsafe fn foo(self: *const Self) -> *const str {
+        (*self).0.as_ref()
+    }
+
+    fn complicated_1(self: *const Rc<Self>) -> &'static str {
+        "Foo::complicated_1"
+    }
+
+    unsafe fn complicated_2(self: Rc<*const Self>) -> *const str {
+        (**self).0.as_ref()
+    }
+}
+
+fn main() {
+    let foo = Foo("abc123".into());
+    assert_eq!("abc123", unsafe { &*(&foo as *const Foo).foo() });
+    assert_eq!("Foo::complicated_1", std::ptr::null::<Rc<Foo>>().complicated_1());
+    let rc = Rc::new(&foo as *const Foo);
+    assert_eq!("abc123", unsafe { &*rc.complicated_2()});
+}
diff --git a/src/test/ui/self/arbitrary_self_types_raw_pointer_trait.rs b/src/test/ui/self/arbitrary_self_types_raw_pointer_trait.rs
new file mode 100644
index 00000000000..acbe896eebe
--- /dev/null
+++ b/src/test/ui/self/arbitrary_self_types_raw_pointer_trait.rs
@@ -0,0 +1,61 @@
+// run-pass
+#![feature(arbitrary_self_types)]
+
+use std::ptr;
+
+trait Foo {
+    fn foo(self: *const Self) -> &'static str;
+
+    unsafe fn bar(self: *const Self) -> i64;
+
+    unsafe fn complicated(self: *const *const Self) -> i64 where Self: Sized {
+        (*self).bar()
+    }
+}
+
+impl Foo for i32 {
+    fn foo(self: *const Self) -> &'static str {
+        "I'm an i32!"
+    }
+
+    unsafe fn bar(self: *const Self) -> i64 {
+        *self as i64
+    }
+}
+
+impl Foo for u32 {
+    fn foo(self: *const Self) -> &'static str {
+        "I'm a u32!"
+    }
+
+    unsafe fn bar(self: *const Self) -> i64 {
+        *self as i64
+    }
+}
+
+fn main() {
+    let null_i32 = ptr::null::<i32>() as *const Foo;
+    let null_u32 = ptr::null::<u32>() as *const Foo;
+
+    assert_eq!("I'm an i32!", null_i32.foo());
+    assert_eq!("I'm a u32!", null_u32.foo());
+
+    let valid_i32 = 5i32;
+    let valid_i32_thin = &valid_i32 as *const i32;
+    assert_eq!("I'm an i32!", valid_i32_thin.foo());
+    assert_eq!(5, unsafe { valid_i32_thin.bar() });
+    assert_eq!(5, unsafe { (&valid_i32_thin as *const *const i32).complicated() });
+    let valid_i32_fat = valid_i32_thin as *const Foo;
+    assert_eq!("I'm an i32!", valid_i32_fat.foo());
+    assert_eq!(5, unsafe { valid_i32_fat.bar() });
+
+    let valid_u32 = 18u32;
+    let valid_u32_thin = &valid_u32 as *const u32;
+    assert_eq!("I'm a u32!", valid_u32_thin.foo());
+    assert_eq!(18, unsafe { valid_u32_thin.bar() });
+    assert_eq!(18, unsafe { (&valid_u32_thin as *const *const u32).complicated() });
+    let valid_u32_fat = valid_u32_thin as *const Foo;
+    assert_eq!("I'm a u32!", valid_u32_fat.foo());
+    assert_eq!(18, unsafe { valid_u32_fat.bar() });
+
+}
diff --git a/src/test/ui/self/arbitrary_self_types_silly.rs b/src/test/ui/self/arbitrary_self_types_silly.rs
new file mode 100644
index 00000000000..fb5f9012b18
--- /dev/null
+++ b/src/test/ui/self/arbitrary_self_types_silly.rs
@@ -0,0 +1,21 @@
+// run-pass
+#![feature(arbitrary_self_types)]
+
+struct Foo;
+struct Bar;
+
+impl std::ops::Deref for Bar {
+    type Target = Foo;
+
+    fn deref(&self) -> &Foo {
+        &Foo
+    }
+}
+
+impl Foo {
+    fn bar(self: Bar) -> i32 { 3 }
+}
+
+fn main() {
+    assert_eq!(3, Bar.bar());
+}
diff --git a/src/test/ui/self/arbitrary_self_types_stdlib_pointers.rs b/src/test/ui/self/arbitrary_self_types_stdlib_pointers.rs
new file mode 100644
index 00000000000..29563fbbd86
--- /dev/null
+++ b/src/test/ui/self/arbitrary_self_types_stdlib_pointers.rs
@@ -0,0 +1,54 @@
+// run-pass
+#![feature(arbitrary_self_types)]
+#![feature(rustc_attrs)]
+
+use std::{
+    rc::Rc,
+    sync::Arc,
+    pin::Pin,
+};
+
+trait Trait {
+    fn by_rc(self: Rc<Self>) -> i64;
+    fn by_arc(self: Arc<Self>) -> i64;
+    fn by_pin_mut(self: Pin<&mut Self>) -> i64;
+    fn by_pin_box(self: Pin<Box<Self>>) -> i64;
+    fn by_pin_pin_pin_ref(self: Pin<Pin<Pin<&Self>>>) -> i64;
+}
+
+impl Trait for i64 {
+    fn by_rc(self: Rc<Self>) -> i64 {
+        *self
+    }
+    fn by_arc(self: Arc<Self>) -> i64 {
+        *self
+    }
+    fn by_pin_mut(self: Pin<&mut Self>) -> i64 {
+        *self
+    }
+    fn by_pin_box(self: Pin<Box<Self>>) -> i64 {
+        *self
+    }
+    fn by_pin_pin_pin_ref(self: Pin<Pin<Pin<&Self>>>) -> i64 {
+        *self
+    }
+}
+
+fn main() {
+    let rc = Rc::new(1i64) as Rc<dyn Trait>;
+    assert_eq!(1, rc.by_rc());
+
+    let arc = Arc::new(2i64) as Arc<dyn Trait>;
+    assert_eq!(2, arc.by_arc());
+
+    let mut value = 3i64;
+    let pin_mut = Pin::new(&mut value) as Pin<&mut dyn Trait>;
+    assert_eq!(3, pin_mut.by_pin_mut());
+
+    let pin_box = Into::<Pin<Box<i64>>>::into(Box::new(4i64)) as Pin<Box<dyn Trait>>;
+    assert_eq!(4, pin_box.by_pin_box());
+
+    let value = 5i64;
+    let pin_pin_pin_ref = Pin::new(Pin::new(Pin::new(&value))) as Pin<Pin<Pin<&dyn Trait>>>;
+    assert_eq!(5, pin_pin_pin_ref.by_pin_pin_pin_ref());
+}
diff --git a/src/test/ui/self/arbitrary_self_types_struct.rs b/src/test/ui/self/arbitrary_self_types_struct.rs
new file mode 100644
index 00000000000..cf62cd3a4e6
--- /dev/null
+++ b/src/test/ui/self/arbitrary_self_types_struct.rs
@@ -0,0 +1,25 @@
+// run-pass
+#![feature(arbitrary_self_types)]
+
+use std::rc::Rc;
+
+struct Foo {
+    x: i32,
+    y: i32,
+}
+
+impl Foo {
+    fn x(self: &Rc<Self>) -> i32 {
+        self.x
+    }
+
+    fn y(self: Rc<Self>) -> i32 {
+        self.y
+    }
+}
+
+fn main() {
+    let foo = Rc::new(Foo {x: 3, y: 4});
+    assert_eq!(3, foo.x());
+    assert_eq!(4, foo.y());
+}
diff --git a/src/test/ui/self/arbitrary_self_types_trait.rs b/src/test/ui/self/arbitrary_self_types_trait.rs
new file mode 100644
index 00000000000..fb06344df7e
--- /dev/null
+++ b/src/test/ui/self/arbitrary_self_types_trait.rs
@@ -0,0 +1,20 @@
+// run-pass
+#![feature(arbitrary_self_types)]
+
+use std::rc::Rc;
+
+trait Trait {
+    fn trait_method<'a>(self: &'a Box<Rc<Self>>) -> &'a [i32];
+}
+
+impl Trait for Vec<i32> {
+    fn trait_method<'a>(self: &'a Box<Rc<Self>>) -> &'a [i32] {
+        &***self
+    }
+}
+
+fn main() {
+    let v = vec![1,2,3];
+
+    assert_eq!(&[1,2,3], Box::new(Rc::new(v)).trait_method());
+}
diff --git a/src/test/ui/self/arbitrary_self_types_unsized_struct.rs b/src/test/ui/self/arbitrary_self_types_unsized_struct.rs
new file mode 100644
index 00000000000..b78223fd57c
--- /dev/null
+++ b/src/test/ui/self/arbitrary_self_types_unsized_struct.rs
@@ -0,0 +1,17 @@
+// run-pass
+#![feature(arbitrary_self_types)]
+
+use std::rc::Rc;
+
+struct Foo<T: ?Sized>(T);
+
+impl Foo<[u8]> {
+    fn len(self: Rc<Self>) -> usize {
+        self.0.len()
+    }
+}
+
+fn main() {
+    let rc = Rc::new(Foo([1u8,2,3])) as Rc<Foo<[u8]>>;
+    assert_eq!(3, rc.len());
+}