Skip to content

Commit

Permalink
Auto merge of #2033 - RalfJung:arbitrary-self-dyn, r=RalfJung
Browse files Browse the repository at this point in the history
test arbitrary-self dyn receivers

Requires rust-lang/rust#95071
  • Loading branch information
bors committed Mar 20, 2022
2 parents a64e6fd + b066856 commit 16c69fd
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 1 deletion.
2 changes: 1 addition & 1 deletion rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
c7ce69faf2a7ea16c15d922985ca27ba70da30ee
9bd53718e2537d95d8c092609618c2dcd6f05127
134 changes: 134 additions & 0 deletions tests/run-pass/dyn-arbitrary-self.rs
Original file line number Diff line number Diff line change
@@ -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<dyn Foo>> = 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<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;
}

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
}
}

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());
}

fn pointers_and_wrappers() {
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
}
}

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);
}


fn main() {
pin_box_dyn();
stdlib_pointers();
pointers_and_wrappers();
}

0 comments on commit 16c69fd

Please sign in to comment.