diff --git a/rust-version b/rust-version index 249d5ad47eb..561d020f120 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -c7ce69faf2a7ea16c15d922985ca27ba70da30ee +9bd53718e2537d95d8c092609618c2dcd6f05127 diff --git a/tests/run-pass/dyn-arbitrary-self.rs b/tests/run-pass/dyn-arbitrary-self.rs new file mode 100644 index 00000000000..9003c478990 --- /dev/null +++ b/tests/run-pass/dyn-arbitrary-self.rs @@ -0,0 +1,134 @@ +#![feature(arbitrary_self_types, unsize, coerce_unsized, dispatch_from_dyn)] +#![feature(rustc_attrs)] + +fn pin_box_dyn() { + use std::pin::Pin; + + trait Foo { + fn bar(self: Pin<&mut Self>) -> bool; + } + + impl Foo for &'static str { + fn bar(self: Pin<&mut Self>) -> bool { + true + } + } + + let mut test: Pin> = Box::pin("foo"); + test.as_mut().bar(); +} + +fn stdlib_pointers() { + use std::{ + rc::Rc, + sync::Arc, + pin::Pin, + }; + + trait Trait { + fn by_rc(self: Rc) -> i64; + fn by_arc(self: Arc) -> i64; + fn by_pin_mut(self: Pin<&mut Self>) -> i64; + fn by_pin_box(self: Pin>) -> i64; + } + + impl Trait for i64 { + fn by_rc(self: Rc) -> i64 { + *self + } + fn by_arc(self: Arc) -> i64 { + *self + } + fn by_pin_mut(self: Pin<&mut Self>) -> i64 { + *self + } + fn by_pin_box(self: Pin>) -> i64 { + *self + } + } + + let rc = Rc::new(1i64) as Rc; + assert_eq!(1, rc.by_rc()); + + let arc = Arc::new(2i64) as Arc; + 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::>>::into(Box::new(4i64)) as Pin>; + assert_eq!(4, pin_box.by_pin_box()); +} + +fn pointers_and_wrappers() { + use std::{ + ops::{Deref, CoerceUnsized, DispatchFromDyn}, + marker::Unsize, + }; + + struct Ptr(Box); + + impl Deref for Ptr { + type Target = T; + + fn deref(&self) -> &T { + &*self.0 + } + } + + impl + ?Sized, U: ?Sized> CoerceUnsized> for Ptr {} + impl + ?Sized, U: ?Sized> DispatchFromDyn> for Ptr {} + + struct Wrapper(T); + + impl Deref for Wrapper { + type Target = T; + + fn deref(&self) -> &T { + &self.0 + } + } + + impl, U> CoerceUnsized> for Wrapper {} + impl, U> DispatchFromDyn> for Wrapper {} + + + 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) -> i32; + fn ptr_wrapper(self: Ptr>) -> i32; + fn wrapper_ptr(self: Wrapper>) -> i32; + fn wrapper_ptr_wrapper(self: Wrapper>>) -> i32; + } + + impl Trait for i32 { + fn ptr_wrapper(self: Ptr>) -> i32 { + **self + } + fn wrapper_ptr(self: Wrapper>) -> i32 { + **self + } + fn wrapper_ptr_wrapper(self: Wrapper>>) -> i32 { + ***self + } + } + + let pw = Ptr(Box::new(Wrapper(5))) as Ptr>; + assert_eq!(pw.ptr_wrapper(), 5); + + let wp = Wrapper(Ptr(Box::new(6))) as Wrapper>; + assert_eq!(wp.wrapper_ptr(), 6); + + let wpw = Wrapper(Ptr(Box::new(Wrapper(7)))) as Wrapper>>; + assert_eq!(wpw.wrapper_ptr_wrapper(), 7); +} + + +fn main() { + pin_box_dyn(); + stdlib_pointers(); + pointers_and_wrappers(); +}