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