1 #![feature(unsized_locals, unsized_fn_params)]
2 #![allow(incomplete_features)]
3 
ref_box_dyn()4 fn ref_box_dyn() {
5     struct Struct(i32);
6 
7     trait Trait {
8         fn method(&self);
9 
10         fn box_method(self: Box<Self>);
11     }
12 
13     impl Trait for Struct {
14         fn method(&self) {
15             assert_eq!(self.0, 42);
16         }
17 
18         fn box_method(self: Box<Self>) {
19             assert_eq!(self.0, 7);
20         }
21     }
22 
23     struct Foo<T: ?Sized>(T);
24 
25     let y: &dyn Trait = &Struct(42);
26     y.method();
27 
28     let x: Foo<Struct> = Foo(Struct(42));
29     let y: &Foo<dyn Trait> = &x;
30     y.0.method();
31 
32     let y: Box<dyn Trait> = Box::new(Struct(42));
33     y.method();
34 
35     let y = &y;
36     y.method();
37 
38     let y: Box<dyn Trait> = Box::new(Struct(7));
39     y.box_method();
40 }
41 
42 
box_box_trait()43 fn box_box_trait() {
44     struct DroppableStruct;
45 
46     static mut DROPPED: bool = false;
47 
48     impl Drop for DroppableStruct {
49         fn drop(&mut self) {
50             unsafe { DROPPED = true; }
51         }
52     }
53 
54     trait MyTrait { fn dummy(&self) { } }
55     impl MyTrait for Box<DroppableStruct> {}
56 
57     struct Whatever { w: Box<dyn MyTrait+'static> }
58 
59     impl  Whatever {
60         fn new(w: Box<dyn MyTrait+'static>) -> Whatever {
61             Whatever { w: w }
62         }
63     }
64 
65     {
66         let f = Box::new(DroppableStruct);
67         let a = Whatever::new(Box::new(f) as Box<dyn MyTrait>);
68         a.w.dummy();
69     }
70     assert!(unsafe { DROPPED });
71 }
72 
unsized_dyn()73 fn unsized_dyn() {
74     pub trait Foo {
75         fn foo(self) -> String;
76     }
77 
78     struct A;
79 
80     impl Foo for A {
81         fn foo(self) -> String {
82             format!("hello")
83         }
84     }
85 
86     let x = *(Box::new(A) as Box<dyn Foo>);
87     assert_eq!(x.foo(), format!("hello"));
88 
89     // I'm not sure whether we want this to work
90     let x = Box::new(A) as Box<dyn Foo>;
91     assert_eq!(x.foo(), format!("hello"));
92 }
93 
unsized_dyn_autoderef()94 fn unsized_dyn_autoderef() {
95     pub trait Foo {
96         fn foo(self) -> String;
97     }
98 
99     impl Foo for [char] {
100         fn foo(self) -> String {
101             self.iter().collect()
102         }
103     }
104 
105     impl Foo for str {
106         fn foo(self) -> String {
107             self.to_owned()
108         }
109     }
110 
111     impl Foo for dyn FnMut() -> String {
112         fn foo(mut self) -> String {
113             self()
114         }
115     }
116 
117     let x = *(Box::new(['h', 'e', 'l', 'l', 'o']) as Box<[char]>);
118     assert_eq!(&x.foo() as &str, "hello");
119 
120     let x = Box::new(['h', 'e', 'l', 'l', 'o']) as Box<[char]>;
121     assert_eq!(&x.foo() as &str, "hello");
122 
123     let x = "hello".to_owned().into_boxed_str();
124     assert_eq!(&x.foo() as &str, "hello");
125 
126     let x = *("hello".to_owned().into_boxed_str());
127     assert_eq!(&x.foo() as &str, "hello");
128 
129     let x = "hello".to_owned().into_boxed_str();
130     assert_eq!(&x.foo() as &str, "hello");
131 
132     let x = *(Box::new(|| "hello".to_owned()) as Box<dyn FnMut() -> String>);
133     assert_eq!(&x.foo() as &str, "hello");
134 
135     let x = Box::new(|| "hello".to_owned()) as Box<dyn FnMut() -> String>;
136     assert_eq!(&x.foo() as &str, "hello");
137 }
138 
main()139 fn main() {
140     ref_box_dyn();
141     box_box_trait();
142 
143     // "exotic" receivers
144     unsized_dyn();
145     unsized_dyn_autoderef();
146 }
147