conditional_panic/
conditional_panic.rs

1//! Example of inherently panicking system.
2//!
3//! Any machine-check formal verification of this system
4//! should return an inherent panic error with "Example panic 2"
5//! reached, as it is possible to reach it with a certain input.
6//!
7//! Only the things specific to the inherent panics will be commented
8//! here. See the example "counter" for a basic description
9//! of a machine-check system.
10
11#[machine_check::machine_description]
12mod machine_module {
13    use ::machine_check::Bitvector;
14    use ::std::{
15        clone::Clone,
16        cmp::{Eq, PartialEq},
17        fmt::Debug,
18        hash::Hash,
19    };
20
21    #[derive(Clone, PartialEq, Eq, Hash, Debug)]
22    pub struct Input {
23        panic_input: Bitvector<8>,
24    }
25
26    impl ::machine_check::Input for Input {}
27
28    #[derive(Clone, PartialEq, Eq, Hash, Debug)]
29    pub struct State {}
30
31    impl ::machine_check::State for State {}
32
33    #[derive(Clone, PartialEq, Eq, Hash, Debug)]
34    pub struct System {}
35
36    // We can define support functions in inherent
37    // system implementations.
38    #[allow(dead_code, unreachable_code)]
39    impl System {
40        // This function simply panics.
41        // Currently, the treatment of panic as diverging
42        // is not supported, so the result must be still
43        // produced.
44        fn example_fn() -> ::machine_check::Bitvector<8> {
45            ::std::panic!("Example panic 1");
46            ::machine_check::Bitvector::<8>::new(0)
47        }
48    }
49
50    #[allow(unused_variables)]
51    impl ::machine_check::Machine for System {
52        type Input = Input;
53        type State = State;
54
55        fn init(&self, input: &Input) -> State {
56            State {}
57        }
58
59        #[allow(unreachable_code)]
60        fn next(&self, state: &State, input: &Input) -> State {
61            // Do not execute the following block.
62            if false {
63                // The example function can be called as an associated
64                // method, and would always panic (you can try it
65                // by changing the condition).
66                //
67                // Currently, it is necessary to assign the result
68                // to a variable. Since discovering the return type of other
69                // methods is not supported yet, its type must be explicitly
70                // specified.
71                let a: ::machine_check::Bitvector<8> = Self::example_fn();
72            }
73            // Panic if the input field panic_input is equal to 1.
74            if input.panic_input == Bitvector::<8>::new(1) {
75                // The first panic should win, i.e. "Example panic 2"
76                // inherent panic error should be returned when formally
77                // verifying with machine-check.
78                ::std::panic!("Example panic 2");
79                ::std::panic!("Example panic 3");
80            }
81            State {}
82        }
83    }
84}
85
86fn main() {
87    let system = machine_module::System {};
88    machine_check::run(system);
89}