1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//! # Snapshot type
//!
//! The type snapshot for a given type `T`.
//!
//! ## Layout
//!
//! Its layout is that of whatever it wraps. In other words, if it was Rust it would be equivalent
//! to the following:
//!
//! ```
//! #[repr(transparent)]
//! pub struct Snapshot<T>(pub T);
//! ```
use super::{TypeBuilder, WithSelf};
use crate::{
error::Result,
metadata::{enum_snapshot_variants::EnumSnapshotVariantsMeta, MetadataStorage},
utils::ProgramRegistryExt,
};
use cairo_lang_sierra::{
extensions::{
core::{CoreLibfunc, CoreType},
types::InfoAndTypeConcreteType,
},
program_registry::ProgramRegistry,
};
use melior::ir::{Module, Type};
use melior::Context;
/// Build the MLIR type.
///
/// Check out [the module](self) for more info.
pub fn build<'ctx>(
context: &'ctx Context,
module: &Module<'ctx>,
registry: &ProgramRegistry<CoreType, CoreLibfunc>,
metadata: &mut MetadataStorage,
info: WithSelf<InfoAndTypeConcreteType>,
) -> Result<Type<'ctx>> {
// This type is like a `Cow<T>` that clones whenever the original type is modified to keep the
// original data. Since implementing that is complicated we can just clone the entire value for
// now.
// Register enum variants for the snapshot.
if let Some(variants) = registry.get_type(&info.ty)?.variants() {
metadata
.get_or_insert_with(EnumSnapshotVariantsMeta::default)
.set_mapping(info.self_ty, variants);
}
registry.build_type(context, module, metadata, &info.ty)
}