]> git.lizzy.rs Git - rust.git/blob - tests/ui/nullable-pointer-iotareduction.rs
Rollup merge of #106692 - eggyal:mv-binary_heap.rs-binary_heap/mod.rs, r=Mark-Simulacrum
[rust.git] / tests / ui / nullable-pointer-iotareduction.rs
1 // run-pass
2
3 // Iota-reduction is a rule in the Calculus of (Co-)Inductive Constructions,
4 // which "says that a destructor applied to an object built from a constructor
5 // behaves as expected".  -- https://coq.inria.fr/doc/language/core/conversion.html#iota-reduction
6 //
7 // It's a little more complicated here, because of pointers and regions and
8 // trying to get assert failure messages that at least identify which case
9 // failed.
10
11 enum E<T> { Thing(isize, T), #[allow(unused_tuple_struct_fields)] Nothing((), ((), ()), [i8; 0]) }
12 impl<T> E<T> {
13     fn is_none(&self) -> bool {
14         match *self {
15             E::Thing(..) => false,
16             E::Nothing(..) => true
17         }
18     }
19     fn get_ref(&self) -> (isize, &T) {
20         match *self {
21             E::Nothing(..) => panic!("E::get_ref(Nothing::<{}>)",  stringify!(T)),
22             E::Thing(x, ref y) => (x, y)
23         }
24     }
25 }
26
27 macro_rules! check_option {
28     ($e:expr, $T:ty) => {{
29         check_option!($e, $T, |ptr| assert_eq!(*ptr, $e));
30     }};
31     ($e:expr, $T:ty, |$v:ident| $chk:expr) => {{
32         assert!(None::<$T>.is_none());
33         let e = $e;
34         let s_ = Some::<$T>(e);
35         let $v = s_.as_ref().unwrap();
36         $chk
37     }}
38 }
39
40 macro_rules! check_fancy {
41     ($e:expr, $T:ty) => {{
42         check_fancy!($e, $T, |ptr| assert_eq!(*ptr, $e));
43     }};
44     ($e:expr, $T:ty, |$v:ident| $chk:expr) => {{
45         assert!(E::Nothing::<$T>((), ((), ()), [23; 0]).is_none());
46         let e = $e;
47         let t_ = E::Thing::<$T>(23, e);
48         match t_.get_ref() {
49             (23, $v) => { $chk }
50             _ => panic!("Thing::<{}>(23, {}).get_ref() != (23, _)",
51                        stringify!($T), stringify!($e))
52         }
53     }}
54 }
55
56 macro_rules! check_type {
57     ($($a:tt)*) => {{
58         check_option!($($a)*);
59         check_fancy!($($a)*);
60     }}
61 }
62
63 pub fn main() {
64     check_type!(&17, &isize);
65     check_type!(Box::new(18), Box<isize>);
66     check_type!("foo".to_string(), String);
67     check_type!(vec![20, 22], Vec<isize>);
68     check_type!(main, fn(), |pthing| {
69         assert_eq!(main as fn(), *pthing as fn())
70     });
71 }