fn ref_box_dyn() { struct Struct(i32); trait Trait { fn method(&self); fn box_method(self: Box); } impl Trait for Struct { fn method(&self) { assert_eq!(self.0, 42); } fn box_method(self: Box) { assert_eq!(self.0, 7); } } struct Foo(T); let y: &dyn Trait = &Struct(42); y.method(); let x: Foo = Foo(Struct(42)); let y: &Foo = &x; y.0.method(); let y: Box = Box::new(Struct(42)); y.method(); let y = &y; y.method(); let y: Box = Box::new(Struct(7)); y.box_method(); } 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 }); } // Disabled for now: unsized locals are not supported, // their current MIR encoding is just not great. /* 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_box_dyn(); box_box_trait(); }