]> git.lizzy.rs Git - rust.git/blob - src/tools/miri/tests/pass/dyn-upcast.rs
Auto merge of #104915 - weihanglo:update-cargo, r=ehuss
[rust.git] / src / tools / miri / tests / pass / dyn-upcast.rs
1 #![feature(trait_upcasting)]
2 #![allow(incomplete_features)]
3
4 fn main() {
5     basic();
6     diamond();
7     struct_();
8     replace_vptr();
9     vtable_mismatch_nop_cast();
10 }
11
12 fn vtable_mismatch_nop_cast() {
13     let ptr: &dyn std::fmt::Display = &0;
14     // Even though the vtable is for the wrong trait, this cast doesn't actually change the needed
15     // vtable so it should still be allowed.
16     let ptr: *const (dyn std::fmt::Debug + Send + Sync) = unsafe { std::mem::transmute(ptr) };
17     let _ptr2 = ptr as *const dyn std::fmt::Debug;
18 }
19
20 fn basic() {
21     trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
22         fn a(&self) -> i32 {
23             10
24         }
25
26         fn z(&self) -> i32 {
27             11
28         }
29
30         fn y(&self) -> i32 {
31             12
32         }
33     }
34
35     trait Bar: Foo {
36         fn b(&self) -> i32 {
37             20
38         }
39
40         fn w(&self) -> i32 {
41             21
42         }
43     }
44
45     trait Baz: Bar {
46         fn c(&self) -> i32 {
47             30
48         }
49     }
50
51     impl Foo for i32 {
52         fn a(&self) -> i32 {
53             100
54         }
55     }
56
57     impl Bar for i32 {
58         fn b(&self) -> i32 {
59             200
60         }
61     }
62
63     impl Baz for i32 {
64         fn c(&self) -> i32 {
65             300
66         }
67     }
68
69     let baz: &dyn Baz = &1;
70     let _: &dyn std::fmt::Debug = baz;
71     assert_eq!(*baz, 1);
72     assert_eq!(baz.a(), 100);
73     assert_eq!(baz.b(), 200);
74     assert_eq!(baz.c(), 300);
75     assert_eq!(baz.z(), 11);
76     assert_eq!(baz.y(), 12);
77     assert_eq!(baz.w(), 21);
78
79     let bar: &dyn Bar = baz;
80     let _: &dyn std::fmt::Debug = bar;
81     assert_eq!(*bar, 1);
82     assert_eq!(bar.a(), 100);
83     assert_eq!(bar.b(), 200);
84     assert_eq!(bar.z(), 11);
85     assert_eq!(bar.y(), 12);
86     assert_eq!(bar.w(), 21);
87
88     let foo: &dyn Foo = baz;
89     let _: &dyn std::fmt::Debug = foo;
90     assert_eq!(*foo, 1);
91     assert_eq!(foo.a(), 100);
92     assert_eq!(foo.z(), 11);
93     assert_eq!(foo.y(), 12);
94
95     let foo: &dyn Foo = bar;
96     let _: &dyn std::fmt::Debug = foo;
97     assert_eq!(*foo, 1);
98     assert_eq!(foo.a(), 100);
99     assert_eq!(foo.z(), 11);
100     assert_eq!(foo.y(), 12);
101 }
102
103 fn diamond() {
104     trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
105         fn a(&self) -> i32 {
106             10
107         }
108
109         fn z(&self) -> i32 {
110             11
111         }
112
113         fn y(&self) -> i32 {
114             12
115         }
116     }
117
118     trait Bar1: Foo {
119         fn b(&self) -> i32 {
120             20
121         }
122
123         fn w(&self) -> i32 {
124             21
125         }
126     }
127
128     trait Bar2: Foo {
129         fn c(&self) -> i32 {
130             30
131         }
132
133         fn v(&self) -> i32 {
134             31
135         }
136     }
137
138     trait Baz: Bar1 + Bar2 {
139         fn d(&self) -> i32 {
140             40
141         }
142     }
143
144     impl Foo for i32 {
145         fn a(&self) -> i32 {
146             100
147         }
148     }
149
150     impl Bar1 for i32 {
151         fn b(&self) -> i32 {
152             200
153         }
154     }
155
156     impl Bar2 for i32 {
157         fn c(&self) -> i32 {
158             300
159         }
160     }
161
162     impl Baz for i32 {
163         fn d(&self) -> i32 {
164             400
165         }
166     }
167
168     let baz: &dyn Baz = &1;
169     let _: &dyn std::fmt::Debug = baz;
170     assert_eq!(*baz, 1);
171     assert_eq!(baz.a(), 100);
172     assert_eq!(baz.b(), 200);
173     assert_eq!(baz.c(), 300);
174     assert_eq!(baz.d(), 400);
175     assert_eq!(baz.z(), 11);
176     assert_eq!(baz.y(), 12);
177     assert_eq!(baz.w(), 21);
178     assert_eq!(baz.v(), 31);
179
180     let bar1: &dyn Bar1 = baz;
181     let _: &dyn std::fmt::Debug = bar1;
182     assert_eq!(*bar1, 1);
183     assert_eq!(bar1.a(), 100);
184     assert_eq!(bar1.b(), 200);
185     assert_eq!(bar1.z(), 11);
186     assert_eq!(bar1.y(), 12);
187     assert_eq!(bar1.w(), 21);
188
189     let bar2: &dyn Bar2 = baz;
190     let _: &dyn std::fmt::Debug = bar2;
191     assert_eq!(*bar2, 1);
192     assert_eq!(bar2.a(), 100);
193     assert_eq!(bar2.c(), 300);
194     assert_eq!(bar2.z(), 11);
195     assert_eq!(bar2.y(), 12);
196     assert_eq!(bar2.v(), 31);
197
198     let foo: &dyn Foo = baz;
199     let _: &dyn std::fmt::Debug = foo;
200     assert_eq!(*foo, 1);
201     assert_eq!(foo.a(), 100);
202
203     let foo: &dyn Foo = bar1;
204     let _: &dyn std::fmt::Debug = foo;
205     assert_eq!(*foo, 1);
206     assert_eq!(foo.a(), 100);
207
208     let foo: &dyn Foo = bar2;
209     let _: &dyn std::fmt::Debug = foo;
210     assert_eq!(*foo, 1);
211     assert_eq!(foo.a(), 100);
212 }
213
214 fn struct_() {
215     use std::rc::Rc;
216     use std::sync::Arc;
217
218     trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
219         fn a(&self) -> i32 {
220             10
221         }
222
223         fn z(&self) -> i32 {
224             11
225         }
226
227         fn y(&self) -> i32 {
228             12
229         }
230     }
231
232     trait Bar: Foo {
233         fn b(&self) -> i32 {
234             20
235         }
236
237         fn w(&self) -> i32 {
238             21
239         }
240     }
241
242     trait Baz: Bar {
243         fn c(&self) -> i32 {
244             30
245         }
246     }
247
248     impl Foo for i32 {
249         fn a(&self) -> i32 {
250             100
251         }
252     }
253
254     impl Bar for i32 {
255         fn b(&self) -> i32 {
256             200
257         }
258     }
259
260     impl Baz for i32 {
261         fn c(&self) -> i32 {
262             300
263         }
264     }
265
266     fn test_box() {
267         let v = Box::new(1);
268
269         let baz: Box<dyn Baz> = v.clone();
270         assert_eq!(*baz, 1);
271         assert_eq!(baz.a(), 100);
272         assert_eq!(baz.b(), 200);
273         assert_eq!(baz.c(), 300);
274         assert_eq!(baz.z(), 11);
275         assert_eq!(baz.y(), 12);
276         assert_eq!(baz.w(), 21);
277
278         let baz: Box<dyn Baz> = v.clone();
279         let bar: Box<dyn Bar> = baz;
280         assert_eq!(*bar, 1);
281         assert_eq!(bar.a(), 100);
282         assert_eq!(bar.b(), 200);
283         assert_eq!(bar.z(), 11);
284         assert_eq!(bar.y(), 12);
285         assert_eq!(bar.w(), 21);
286
287         let baz: Box<dyn Baz> = v.clone();
288         let foo: Box<dyn Foo> = baz;
289         assert_eq!(*foo, 1);
290         assert_eq!(foo.a(), 100);
291         assert_eq!(foo.z(), 11);
292         assert_eq!(foo.y(), 12);
293
294         let baz: Box<dyn Baz> = v.clone();
295         let bar: Box<dyn Bar> = baz;
296         let foo: Box<dyn Foo> = bar;
297         assert_eq!(*foo, 1);
298         assert_eq!(foo.a(), 100);
299         assert_eq!(foo.z(), 11);
300         assert_eq!(foo.y(), 12);
301     }
302
303     fn test_rc() {
304         let v = Rc::new(1);
305
306         let baz: Rc<dyn Baz> = v.clone();
307         assert_eq!(*baz, 1);
308         assert_eq!(baz.a(), 100);
309         assert_eq!(baz.b(), 200);
310         assert_eq!(baz.c(), 300);
311         assert_eq!(baz.z(), 11);
312         assert_eq!(baz.y(), 12);
313         assert_eq!(baz.w(), 21);
314
315         let baz: Rc<dyn Baz> = v.clone();
316         let bar: Rc<dyn Bar> = baz;
317         assert_eq!(*bar, 1);
318         assert_eq!(bar.a(), 100);
319         assert_eq!(bar.b(), 200);
320         assert_eq!(bar.z(), 11);
321         assert_eq!(bar.y(), 12);
322         assert_eq!(bar.w(), 21);
323
324         let baz: Rc<dyn Baz> = v.clone();
325         let foo: Rc<dyn Foo> = baz;
326         assert_eq!(*foo, 1);
327         assert_eq!(foo.a(), 100);
328         assert_eq!(foo.z(), 11);
329         assert_eq!(foo.y(), 12);
330
331         let baz: Rc<dyn Baz> = v.clone();
332         let bar: Rc<dyn Bar> = baz;
333         let foo: Rc<dyn Foo> = bar;
334         assert_eq!(*foo, 1);
335         assert_eq!(foo.a(), 100);
336         assert_eq!(foo.z(), 11);
337         assert_eq!(foo.y(), 12);
338         assert_eq!(foo.z(), 11);
339         assert_eq!(foo.y(), 12);
340     }
341
342     fn test_arc() {
343         let v = Arc::new(1);
344
345         let baz: Arc<dyn Baz> = v.clone();
346         assert_eq!(*baz, 1);
347         assert_eq!(baz.a(), 100);
348         assert_eq!(baz.b(), 200);
349         assert_eq!(baz.c(), 300);
350         assert_eq!(baz.z(), 11);
351         assert_eq!(baz.y(), 12);
352         assert_eq!(baz.w(), 21);
353
354         let baz: Arc<dyn Baz> = v.clone();
355         let bar: Arc<dyn Bar> = baz;
356         assert_eq!(*bar, 1);
357         assert_eq!(bar.a(), 100);
358         assert_eq!(bar.b(), 200);
359         assert_eq!(bar.z(), 11);
360         assert_eq!(bar.y(), 12);
361         assert_eq!(bar.w(), 21);
362
363         let baz: Arc<dyn Baz> = v.clone();
364         let foo: Arc<dyn Foo> = baz;
365         assert_eq!(*foo, 1);
366         assert_eq!(foo.a(), 100);
367         assert_eq!(foo.z(), 11);
368         assert_eq!(foo.y(), 12);
369
370         let baz: Arc<dyn Baz> = v.clone();
371         let bar: Arc<dyn Bar> = baz;
372         let foo: Arc<dyn Foo> = bar;
373         assert_eq!(*foo, 1);
374         assert_eq!(foo.a(), 100);
375         assert_eq!(foo.z(), 11);
376         assert_eq!(foo.y(), 12);
377     }
378
379     test_box();
380     test_rc();
381     test_arc();
382 }
383
384 fn replace_vptr() {
385     trait A {
386         fn foo_a(&self);
387     }
388
389     trait B {
390         fn foo_b(&self);
391     }
392
393     trait C: A + B {
394         fn foo_c(&self);
395     }
396
397     struct S(i32);
398
399     impl A for S {
400         fn foo_a(&self) {
401             unreachable!();
402         }
403     }
404
405     impl B for S {
406         fn foo_b(&self) {
407             assert_eq!(42, self.0);
408         }
409     }
410
411     impl C for S {
412         fn foo_c(&self) {
413             unreachable!();
414         }
415     }
416
417     fn invoke_inner(b: &dyn B) {
418         b.foo_b();
419     }
420
421     fn invoke_outer(c: &dyn C) {
422         invoke_inner(c);
423     }
424
425     let s = S(42);
426     invoke_outer(&s);
427 }