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