]> git.lizzy.rs Git - rust.git/blob - src/tools/miri/tests/pass/coercions.rs
Auto merge of #104915 - weihanglo:update-cargo, r=ehuss
[rust.git] / src / tools / miri / tests / pass / coercions.rs
1 #![feature(coerce_unsized, unsize)]
2
3 use std::marker::Unsize;
4 use std::ops::CoerceUnsized;
5
6 fn identity_coercion(x: &(dyn Fn(u32) -> u32 + Send)) -> &dyn Fn(u32) -> u32 {
7     x
8 }
9 fn fn_coercions(f: &fn(u32) -> u32) -> (unsafe fn(u32) -> u32, &(dyn Fn(u32) -> u32 + Send)) {
10     (*f, f)
11 }
12
13 fn simple_array_coercion(x: &[u8; 3]) -> &[u8] {
14     x
15 }
16
17 fn square(a: u32) -> u32 {
18     a * a
19 }
20
21 #[derive(PartialEq, Eq)]
22 struct PtrWrapper<'a, T: 'a + ?Sized>(u32, u32, (), &'a T);
23 impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<PtrWrapper<'a, U>> for PtrWrapper<'a, T> {}
24
25 struct TrivPtrWrapper<'a, T: 'a + ?Sized>(&'a T);
26 impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<TrivPtrWrapper<'a, U>>
27     for TrivPtrWrapper<'a, T>
28 {
29 }
30
31 fn coerce_ptr_wrapper(p: PtrWrapper<[u8; 3]>) -> PtrWrapper<[u8]> {
32     p
33 }
34
35 fn coerce_triv_ptr_wrapper(p: TrivPtrWrapper<[u8; 3]>) -> TrivPtrWrapper<[u8]> {
36     p
37 }
38
39 fn coerce_fat_ptr_wrapper(
40     p: PtrWrapper<dyn Fn(u32) -> u32 + Send>,
41 ) -> PtrWrapper<dyn Fn(u32) -> u32> {
42     p
43 }
44
45 fn coerce_ptr_wrapper_poly<'a, T, Trait: ?Sized>(p: PtrWrapper<'a, T>) -> PtrWrapper<'a, Trait>
46 where
47     PtrWrapper<'a, T>: CoerceUnsized<PtrWrapper<'a, Trait>>,
48 {
49     p
50 }
51
52 fn main() {
53     let a = [0, 1, 2];
54     let square_local: fn(u32) -> u32 = square;
55     let (f, g) = fn_coercions(&square_local);
56     // cannot use `square as *const ()` because we can't know whether the compiler duplicates
57     // functions, so two function pointers are only equal if they result from the same function
58     // to function pointer cast
59     assert_eq!(f as *const (), square_local as *const ());
60     assert_eq!(g(4), 16);
61     assert_eq!(identity_coercion(g)(5), 25);
62
63     assert_eq!(simple_array_coercion(&a), &a);
64     let w = coerce_ptr_wrapper(PtrWrapper(2, 3, (), &a));
65     assert!(w == PtrWrapper(2, 3, (), &a) as PtrWrapper<[u8]>);
66
67     let w = coerce_triv_ptr_wrapper(TrivPtrWrapper(&a));
68     assert_eq!(&w.0, &a);
69
70     let z = coerce_fat_ptr_wrapper(PtrWrapper(2, 3, (), &square_local));
71     assert_eq!((z.3)(6), 36);
72
73     let z: PtrWrapper<dyn Fn(u32) -> u32> =
74         coerce_ptr_wrapper_poly(PtrWrapper(2, 3, (), &square_local));
75     assert_eq!((z.3)(6), 36);
76 }