#![feature(unsized_locals)] fn ref_dyn() { struct Struct(i32); trait Trait { fn method(&self); } impl Trait for Struct { fn method(&self) { assert_eq!(self.0, 42); } } struct Foo(T); let y: &dyn Trait = &Struct(42); y.method(); let x: Foo = Foo(Struct(42)); let y: &Foo = &x; y.0.method(); } fn box_dyn() { let x: Box i32> = Box::new(|x| x * 2); assert_eq!(x(21), 42); let mut i = 5; { let mut x: Box = Box::new(|| i *= 2); x(); x(); } assert_eq!(i, 20); } fn box_box_trait() { struct DroppableStruct; static mut DROPPED: bool = false; impl Drop for DroppableStruct { fn drop(&mut self) { unsafe { DROPPED = true; } } } trait MyTrait { fn dummy(&self) { } } impl MyTrait for Box {} struct Whatever { w: Box } impl Whatever { fn new(w: Box) -> Whatever { Whatever { w: w } } } { let f = Box::new(DroppableStruct); let a = Whatever::new(Box::new(f) as Box); a.w.dummy(); } assert!(unsafe { DROPPED }); } fn unsized_dyn() { pub trait Foo { fn foo(self) -> String; } struct A; impl Foo for A { fn foo(self) -> String { format!("hello") } } let x = *(Box::new(A) as Box); assert_eq!(x.foo(), format!("hello")); // I'm not sure whether we want this to work let x = Box::new(A) as Box; assert_eq!(x.foo(), format!("hello")); } fn unsized_dyn_autoderef() { pub trait Foo { fn foo(self) -> String; } impl Foo for [char] { fn foo(self) -> String { self.iter().collect() } } impl Foo for str { fn foo(self) -> String { self.to_owned() } } impl Foo for dyn FnMut() -> String { fn foo(mut self) -> String { self() } } let x = *(Box::new(['h', 'e', 'l', 'l', 'o']) as Box<[char]>); assert_eq!(&x.foo() as &str, "hello"); let x = Box::new(['h', 'e', 'l', 'l', 'o']) as Box<[char]>; assert_eq!(&x.foo() as &str, "hello"); let x = "hello".to_owned().into_boxed_str(); assert_eq!(&x.foo() as &str, "hello"); let x = *("hello".to_owned().into_boxed_str()); assert_eq!(&x.foo() as &str, "hello"); let x = "hello".to_owned().into_boxed_str(); assert_eq!(&x.foo() as &str, "hello"); let x = *(Box::new(|| "hello".to_owned()) as Box String>); assert_eq!(&x.foo() as &str, "hello"); let x = Box::new(|| "hello".to_owned()) as Box String>; assert_eq!(&x.foo() as &str, "hello"); } fn main() { ref_dyn(); box_dyn(); box_box_trait(); // "exotic" receivers unsized_dyn(); unsized_dyn_autoderef(); }