]> git.lizzy.rs Git - rust.git/blob - tests/ui/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs
Rollup merge of #105784 - yanns:update_stdarch, r=Amanieu
[rust.git] / tests / ui / rfc-2027-object-safe-for-dispatch / manual-self-impl-for-unsafe-obj.rs
1 // Check that we can manually implement an object-unsafe trait for its trait object.
2
3 // run-pass
4
5 #![feature(object_safe_for_dispatch)]
6
7 trait Bad {
8     fn stat() -> char {
9         'A'
10     }
11     fn virt(&self) -> char {
12         'B'
13     }
14     fn indirect(&self) -> char {
15         Self::stat()
16     }
17 }
18
19 trait Good {
20     fn good_virt(&self) -> char {
21         panic!()
22     }
23     fn good_indirect(&self) -> char {
24         panic!()
25     }
26 }
27
28 impl<'a> Bad for dyn Bad + 'a {
29     fn stat() -> char {
30         'C'
31     }
32     fn virt(&self) -> char {
33         'D'
34     }
35 }
36
37 struct Struct {}
38
39 impl Bad for Struct {}
40
41 impl Good for Struct {}
42
43 fn main() {
44     let s = Struct {};
45
46     let mut res = String::new();
47
48     // Directly call static.
49     res.push(Struct::stat()); // "A"
50     res.push(<dyn Bad>::stat()); // "AC"
51
52     let good: &dyn Good = &s;
53
54     // These look similar enough...
55     let bad = unsafe { std::mem::transmute::<&dyn Good, &dyn Bad>(good) };
56
57     // Call virtual.
58     res.push(s.virt()); // "ACB"
59     res.push(bad.virt()); // "ACBD"
60
61     // Indirectly call static.
62     res.push(s.indirect()); // "ACBDA"
63     res.push(bad.indirect()); // "ACBDAC"
64
65     assert_eq!(&res, "ACBDAC");
66 }