Skip to main content

charon_lib/ast/items/
global_decl.rs

1use crate::ast::*;
2use derive_generic_visitor::{Drive, DriveMut, DriveTwo};
3use serde_state::DeserializeState;
4use serde_state::SerializeState;
5
6/// A global variable definition (constant or static).
7#[derive(Debug, Clone, SerializeState, DeserializeState, Drive, DriveMut, DriveTwo)]
8pub struct GlobalDecl {
9    pub def_id: GlobalDeclId,
10    /// The meta data associated with the declaration.
11    pub item_meta: ItemMeta,
12    /// Remark: constants can actually have generic parameters.
13    /// ```text
14    /// struct V<const N: usize, T> {
15    ///     x: [T; N],
16    /// }
17    ///
18    /// impl<const N: usize, T> V<N, T> {
19    ///     const LEN: usize = N; // This has generics <N, T>
20    /// }
21    ///
22    /// fn use_v<const N: usize, T>(v: V<N, T>) {
23    ///     let l = V::<N, T>::LEN; // We need to provided a substitution here
24    /// }
25    /// ```
26    pub generics: GenericParams,
27    pub ty: Ty,
28    /// The context of the global: distinguishes normal items from trait-associated items and
29    /// vtable instances.
30    pub src: GlobalSource,
31    /// The kind of global (static or const).
32    pub global_kind: GlobalKind,
33    /// The value of this constant/static. By default this is a [`ConstantExprKind::Call`] to the
34    /// initializer function that computes the value (the function uses the same generic parameters
35    /// as the global).
36    pub value: ConstantExpr,
37}
38
39#[derive(
40    Debug, PartialEq, Eq, Clone, SerializeState, DeserializeState, Drive, DriveMut, DriveTwo,
41)]
42pub enum GlobalKind {
43    /// A static.
44    Static,
45    /// A thread-local static.
46    ThreadLocal,
47    /// A const with a name (either top-level or an associated const in a trait).
48    NamedConst,
49    /// A const without a name:
50    /// - An inline const expression (`const { 1 + 1 }`);
51    /// - A const expression in a type (`[u8; sizeof::<T>()]`);
52    /// - A promoted constant, automatically lifted from a body (`&0`).
53    AnonConst,
54}
55
56/// Where a given global came from.
57#[derive(Debug, Clone, SerializeState, DeserializeState, Drive, DriveMut, DriveTwo)]
58#[cfg_attr(feature = "charon_on_charon", charon::variants_suffix("Global"))]
59pub enum GlobalSource {
60    /// A normal global.
61    Normal,
62    /// A default assoc const in a trait declaration.
63    TraitDefault {
64        /// The trait declaration the const belongs to.
65        trait_ref: TraitDeclRef,
66        /// The associated const this corresponds to.
67        item_id: AssocConstId,
68    },
69    /// An associated const in a trait implementation.
70    TraitImpl {
71        /// The trait implementation the const belongs to.
72        impl_ref: TraitImplRef,
73        /// The trait declaration that the impl block implements.
74        trait_ref: TraitDeclRef,
75        /// The associated const this corresponds to.
76        item_id: AssocConstId,
77        /// True if the trait decl had a default value for this const and this item is a copy of
78        /// the default item.
79        reuses_default: bool,
80    },
81    /// Defines the vtable for a trait impl.
82    VTableInstance {
83        /// The originating impl. This is `None` in monomorphized mode: the vtable global itself
84        /// identifies the concrete instantiation, so we don't translate an impl reference solely
85        /// to record its provenance.
86        impl_ref: Option<TraitImplRef>,
87    },
88}
89
90impl GlobalDecl {
91    /// If this global's value is a call to its initializer function, returns the initializer's id.
92    pub fn init_fun_id(&self) -> Option<FunDeclId> {
93        match self.value.kind() {
94            ConstantExprKind::Call(fn_ptr, _) => match &*fn_ptr.kind {
95                FnPtrKind::Fun(id) => Some(*id),
96                _ => None,
97            },
98            _ => None,
99        }
100    }
101}