]> git.lizzy.rs Git - rust.git/blob - src/tools/miri/tests/pass/function_pointers.rs
Auto merge of #104915 - weihanglo:update-cargo, r=ehuss
[rust.git] / src / tools / miri / tests / pass / function_pointers.rs
1 use std::mem;
2
3 trait Answer {
4     fn answer() -> Self;
5 }
6
7 impl Answer for i32 {
8     fn answer() -> i32 {
9         42
10     }
11 }
12
13 // A generic function, to make its address unstable
14 fn f<T: Answer>() -> T {
15     Answer::answer()
16 }
17
18 fn g(i: i32) -> i32 {
19     i * 42
20 }
21
22 fn h(i: i32, j: i32) -> i32 {
23     j * i * 7
24 }
25
26 fn return_fn_ptr(f: fn() -> i32) -> fn() -> i32 {
27     f
28 }
29
30 fn call_fn_ptr() -> i32 {
31     return_fn_ptr(f)()
32 }
33
34 fn indirect<F: Fn() -> i32>(f: F) -> i32 {
35     f()
36 }
37 fn indirect_mut<F: FnMut() -> i32>(mut f: F) -> i32 {
38     f()
39 }
40 fn indirect_once<F: FnOnce() -> i32>(f: F) -> i32 {
41     f()
42 }
43
44 fn indirect2<F: Fn(i32) -> i32>(f: F) -> i32 {
45     f(10)
46 }
47 fn indirect_mut2<F: FnMut(i32) -> i32>(mut f: F) -> i32 {
48     f(10)
49 }
50 fn indirect_once2<F: FnOnce(i32) -> i32>(f: F) -> i32 {
51     f(10)
52 }
53
54 fn indirect3<F: Fn(i32, i32) -> i32>(f: F) -> i32 {
55     f(10, 3)
56 }
57 fn indirect_mut3<F: FnMut(i32, i32) -> i32>(mut f: F) -> i32 {
58     f(10, 3)
59 }
60 fn indirect_once3<F: FnOnce(i32, i32) -> i32>(f: F) -> i32 {
61     f(10, 3)
62 }
63
64 fn main() {
65     assert_eq!(call_fn_ptr(), 42);
66     assert_eq!(indirect(f), 42);
67     assert_eq!(indirect_mut(f), 42);
68     assert_eq!(indirect_once(f), 42);
69     assert_eq!(indirect2(g), 420);
70     assert_eq!(indirect_mut2(g), 420);
71     assert_eq!(indirect_once2(g), 420);
72     assert_eq!(indirect3(h), 210);
73     assert_eq!(indirect_mut3(h), 210);
74     assert_eq!(indirect_once3(h), 210);
75     let g = f as fn() -> i32;
76     assert!(return_fn_ptr(g) == g);
77     assert!(return_fn_ptr(g) as unsafe fn() -> i32 == g as fn() -> i32 as unsafe fn() -> i32);
78     assert!(return_fn_ptr(f) != f);
79
80     // Any non-null value is okay for function pointers.
81     unsafe {
82         let _x: fn() = mem::transmute(1usize);
83         let mut b = Box::new(42u8);
84         let ptr = &mut *b as *mut u8;
85         drop(b);
86         let _x: fn() = mem::transmute(ptr);
87         let _x: fn() = mem::transmute(ptr.wrapping_offset(1));
88     }
89 }