rust/tests/pass/function_pointers.rs

90 lines
1.9 KiB
Rust
Raw Normal View History

2022-02-24 09:55:40 -06:00
use std::mem;
2019-02-13 03:07:31 -06:00
trait Answer {
fn answer() -> Self;
}
impl Answer for i32 {
fn answer() -> i32 {
42
}
}
// A generic function, to make its address unstable
fn f<T: Answer>() -> T {
Answer::answer()
2016-06-08 06:43:34 -05:00
}
2016-09-15 09:32:30 -05:00
fn g(i: i32) -> i32 {
i * 42
2016-09-15 09:32:30 -05:00
}
fn h(i: i32, j: i32) -> i32 {
j * i * 7
}
fn return_fn_ptr(f: fn() -> i32) -> fn() -> i32 {
2016-06-08 06:43:34 -05:00
f
}
fn call_fn_ptr() -> i32 {
return_fn_ptr(f)()
2016-06-08 06:43:34 -05:00
}
fn indirect<F: Fn() -> i32>(f: F) -> i32 {
f()
}
fn indirect_mut<F: FnMut() -> i32>(mut f: F) -> i32 {
f()
}
fn indirect_once<F: FnOnce() -> i32>(f: F) -> i32 {
f()
}
2016-09-15 09:32:30 -05:00
fn indirect2<F: Fn(i32) -> i32>(f: F) -> i32 {
f(10)
}
fn indirect_mut2<F: FnMut(i32) -> i32>(mut f: F) -> i32 {
f(10)
}
fn indirect_once2<F: FnOnce(i32) -> i32>(f: F) -> i32 {
f(10)
}
2016-09-15 09:32:30 -05:00
fn indirect3<F: Fn(i32, i32) -> i32>(f: F) -> i32 {
f(10, 3)
}
fn indirect_mut3<F: FnMut(i32, i32) -> i32>(mut f: F) -> i32 {
f(10, 3)
}
fn indirect_once3<F: FnOnce(i32, i32) -> i32>(f: F) -> i32 {
f(10, 3)
}
fn main() {
assert_eq!(call_fn_ptr(), 42);
2016-09-15 09:32:30 -05:00
assert_eq!(indirect(f), 42);
assert_eq!(indirect_mut(f), 42);
assert_eq!(indirect_once(f), 42);
assert_eq!(indirect2(g), 420);
assert_eq!(indirect_mut2(g), 420);
assert_eq!(indirect_once2(g), 420);
assert_eq!(indirect3(h), 210);
assert_eq!(indirect_mut3(h), 210);
assert_eq!(indirect_once3(h), 210);
let g = f as fn() -> i32;
assert!(return_fn_ptr(g) == g);
assert!(return_fn_ptr(g) as unsafe fn() -> i32 == g as fn() -> i32 as unsafe fn() -> i32);
assert!(return_fn_ptr(f) != f);
2022-02-24 09:55:40 -06:00
// Any non-null value is okay for function pointers.
unsafe {
let _x: fn() = mem::transmute(1usize);
2022-02-24 18:41:11 -06:00
let mut b = Box::new(42u8);
let ptr = &mut *b as *mut u8;
2022-02-24 09:55:40 -06:00
drop(b);
let _x: fn() = mem::transmute(ptr);
2022-02-24 18:41:11 -06:00
let _x: fn() = mem::transmute(ptr.wrapping_offset(1));
2022-02-24 09:55:40 -06:00
}
}