diff options
| author | Taiki Endo <te316e89@gmail.com> | 2019-05-19 12:31:08 +0900 |
|---|---|---|
| committer | Taiki Endo <te316e89@gmail.com> | 2019-05-19 12:31:08 +0900 |
| commit | b53d839b239d8fcf4cddfbd565ce5a8836217d5c (patch) | |
| tree | 01070625ca6a6dcc4ed210cae35b6abfeeca8548 /src/test/ui/self | |
| parent | 548add7f61bfcbe3bea3f5ccefb53c84da8fefe4 (diff) | |
| download | rust-b53d839b239d8fcf4cddfbd565ce5a8836217d5c.tar.gz rust-b53d839b239d8fcf4cddfbd565ce5a8836217d5c.zip | |
Move arbitrary_self_types's tests into ui/self
Diffstat (limited to 'src/test/ui/self')
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()); +} |
