Skip to main content

charon_driver/hax/
constant_utils.rs

1use crate::hax::prelude::*;
2
3#[derive(Clone, Debug, Hash, PartialEq, Eq)]
4pub enum ConstantInt {
5    Int(i128, IntTy),
6    Uint(u128, UintTy),
7}
8
9#[derive(Clone, Debug, Hash, PartialEq, Eq)]
10pub enum ConstantLiteral {
11    Bool(bool),
12    Char(char),
13    Float(String, FloatTy),
14    Int(ConstantInt),
15    PtrNoProvenance(u128),
16    Str(String),
17    ByteStr(Vec<u8>),
18}
19
20sinto_reexport!(rustc_abi::VariantIdx);
21
22/// Describe the kind of a variant
23#[derive(Clone, Debug, Hash, PartialEq, Eq)]
24pub enum VariantKind {
25    Struct,
26    Union,
27    Enum { index: VariantIdx },
28}
29
30/// The subset of expressions that corresponds to constants.
31#[derive(Clone, Debug, Hash, PartialEq, Eq)]
32pub enum ConstantExprKind {
33    Literal(ConstantLiteral),
34    // Adts (structs, enums, unions) or closures.
35    Adt {
36        kind: VariantKind,
37        fields: Vec<ConstantFieldExpr>,
38    },
39    Array {
40        fields: Vec<ConstantExpr>,
41    },
42    Tuple {
43        fields: Vec<ConstantExpr>,
44    },
45    /// A top-level or associated constant.
46    ///
47    /// Remark: constants *can* have generic parameters.
48    /// Example:
49    /// ```text
50    /// struct V<const N: usize, T> {
51    ///   x: [T; N],
52    /// }
53    ///
54    /// impl<const N: usize, T> V<N, T> {
55    ///   const LEN: usize = N; // This has generics <N, T>
56    /// }
57    ///
58    /// impl Foo for Bar {
59    ///   const C : usize = 32; // <-
60    /// }
61    /// ```
62    ///
63    /// If `options.inline_anon_consts` is `false`, this is also used for inline const blocks and
64    /// advanced const generics expressions.
65    NamedGlobal(ItemRef),
66    /// A shared reference to a static variable.
67    Borrow(ConstantExpr),
68    /// A raw borrow (`*const` or `*mut`).
69    RawBorrow {
70        mutability: Mutability,
71        arg: ConstantExpr,
72    },
73    ConstRef {
74        id: ParamConst,
75    },
76    /// A function definition, corresponding to a particular item. This is a ZST, unlike `FnPtr`.
77    FnDef(ItemRef),
78    /// A function pointer. This is an actual pointer to that function.
79    FnPtr(ItemRef),
80    /// A blob of memory containing the byte representation of the value. This can occur when
81    /// evaluating MIR constants (e.g. unions). Interpreting this back to a structured value
82    /// is left as an exercice to the consumer.
83    Memory(Vec<ConstantByte>),
84    Todo(String),
85}
86
87/// A byte of an evaluated constant, in the MiniRust sense.
88#[derive(Clone, Debug, Hash, PartialEq, Eq)]
89pub enum ConstantByte {
90    /// An uninitialized byte (e.g. padding, or the bytes of a union not covered by the active
91    /// field).
92    Uninit,
93    /// A concrete byte value.
94    Value(u8),
95    /// A byte that is part of a pointer with provenance. The `u8` is the offset of this byte
96    /// within the pointer.
97    Provenance(ConstantByteProvenance, u8),
98}
99
100/// What a pointer byte in an evaluated constant points to.
101#[derive(Clone, Debug, Hash, PartialEq, Eq)]
102pub enum ConstantByteProvenance {
103    /// A pointer to a static.
104    Global(ItemRef),
105    /// A pointer to a function.
106    Function(ItemRef),
107    /// A pointer to anything else (an anonymous allocation, a vtable...).
108    Unknown,
109}
110
111#[derive(Clone, Debug, Hash, PartialEq, Eq)]
112pub struct ConstantFieldExpr {
113    pub field: DefId,
114    pub value: ConstantExpr,
115}
116
117/// Rustc has different representation for constants: one for MIR
118/// ([`rustc_middle::mir::Const`]), one for the type system
119/// ([`rustc_middle::ty::ConstKind`]). For simplicity hax maps those
120/// two construct to one same `ConstantExpr` type.
121pub type ConstantExpr = Decorated<ConstantExprKind>;
122
123// For ConstantKind we merge all the cases (Ty, Val, Unevaluated) into one
124pub type ConstantKind = ConstantExpr;
125
126pub use self::uneval::*;
127mod uneval;