Skip to main content

vyre_spec/
engine_invariant.rs

1//! Frozen engine-invariant identifiers used by conformance certificates.
2
3use core::fmt;
4
5/// Stable engine invariant identifier in the frozen data contract.
6///
7/// The numeric value matches the `I{N}` naming in the vyre specification.
8/// These numbers are permanent: new invariants add new variants, while
9/// existing variants never change meaning. Example: `EngineInvariant::I4`
10/// identifies the IR wire-format round-trip invariant.
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
12#[non_exhaustive]
13pub enum EngineInvariant {
14    /// I1 Determinism.
15    I1 = 1,
16    /// I2 Composition commutativity with lowering.
17    I2 = 2,
18    /// I3 Backend equivalence.
19    I3 = 3,
20    /// I4 IR wire-format round-trip.
21    I4 = 4,
22    /// I5 Validation soundness.
23    I5 = 5,
24    /// I6 Validation completeness, partial.
25    I6 = 6,
26    /// I7 Law monotonicity under composition.
27    I7 = 7,
28    /// I8 Reference agreement.
29    I8 = 8,
30    /// I9 Law falsifiability.
31    I9 = 9,
32    /// I10 Bounded allocation.
33    I10 = 10,
34    /// I11 No panic.
35    I11 = 11,
36    /// I12 No undefined behaviour.
37    I12 = 12,
38    /// I13 Userspace stability.
39    I13 = 13,
40    /// I14 Non-exhaustive discipline.
41    I14 = 14,
42    /// I15 Certificate stability.
43    I15 = 15,
44}
45
46/// Public alias for stable invariant identifiers.
47pub type InvariantId = EngineInvariant;
48
49impl fmt::Display for EngineInvariant {
50    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51        write!(f, "I{}", self.ordinal())
52    }
53}
54
55impl EngineInvariant {
56    /// Stable one-based invariant number.
57    #[must_use]
58    pub const fn ordinal(&self) -> u8 {
59        match self {
60            Self::I1 => 1,
61            Self::I2 => 2,
62            Self::I3 => 3,
63            Self::I4 => 4,
64            Self::I5 => 5,
65            Self::I6 => 6,
66            Self::I7 => 7,
67            Self::I8 => 8,
68            Self::I9 => 9,
69            Self::I10 => 10,
70            Self::I11 => 11,
71            Self::I12 => 12,
72            Self::I13 => 13,
73            Self::I14 => 14,
74            Self::I15 => 15,
75        }
76    }
77
78    /// Iterate over every known invariant id in declaration order.
79    pub fn iter() -> impl Iterator<Item = Self> {
80        [
81            Self::I1,
82            Self::I2,
83            Self::I3,
84            Self::I4,
85            Self::I5,
86            Self::I6,
87            Self::I7,
88            Self::I8,
89            Self::I9,
90            Self::I10,
91            Self::I11,
92            Self::I12,
93            Self::I13,
94            Self::I14,
95            Self::I15,
96        ]
97        .into_iter()
98    }
99}