cairo_lang_sierra/extensions/
mod.rs

1/// Module for the set of core extensions.
2pub mod core;
3pub mod error;
4pub mod lib_func;
5/// All implementations of basic extensions are under this module.
6pub mod modules;
7pub mod type_specialization_context;
8pub mod types;
9
10use num_bigint::BigInt;
11
12pub use self::error::{ExtensionError, SpecializationError};
13pub use self::lib_func::{
14    ConcreteLibfunc, GenericLibfunc, GenericLibfuncEx, NamedLibfunc, NoGenericArgsGenericLibfunc,
15    OutputVarReferenceInfo, SignatureBasedConcreteLibfunc,
16};
17pub use self::modules::*;
18use self::type_specialization_context::TypeSpecializationContext;
19pub use self::types::{
20    ConcreteType, GenericType, GenericTypeEx, NamedType, NoGenericArgsGenericType,
21};
22use crate::ids::{ConcreteTypeId, FunctionId};
23use crate::program::GenericArg;
24
25/// Helper for extracting the value from the template arguments.
26fn args_as_single_value(args: &[GenericArg]) -> Result<BigInt, SpecializationError> {
27    match args {
28        [GenericArg::Value(c)] => Ok(c.clone()),
29        [_] => Err(SpecializationError::UnsupportedGenericArg),
30        _ => Err(SpecializationError::WrongNumberOfGenericArgs),
31    }
32}
33
34/// Helper for extracting the type from the template arguments.
35pub fn args_as_single_type(args: &[GenericArg]) -> Result<ConcreteTypeId, SpecializationError> {
36    match args {
37        [GenericArg::Type(ty)] => Ok(ty.clone()),
38        [_] => Err(SpecializationError::UnsupportedGenericArg),
39        _ => Err(SpecializationError::WrongNumberOfGenericArgs),
40    }
41}
42
43/// Helper for extracting two types from the template arguments.
44fn args_as_two_types(
45    args: &[GenericArg],
46) -> Result<(ConcreteTypeId, ConcreteTypeId), SpecializationError> {
47    match args {
48        [GenericArg::Type(ty0), GenericArg::Type(ty1)] => Ok((ty0.clone(), ty1.clone())),
49        [_, _] => Err(SpecializationError::UnsupportedGenericArg),
50        _ => Err(SpecializationError::WrongNumberOfGenericArgs),
51    }
52}
53
54/// Helper for extracting the type from the template arguments.
55fn args_as_single_user_func(args: &[GenericArg]) -> Result<FunctionId, SpecializationError> {
56    match args {
57        [GenericArg::UserFunc(function_id)] => Ok(function_id.clone()),
58        [_] => Err(SpecializationError::UnsupportedGenericArg),
59        _ => Err(SpecializationError::WrongNumberOfGenericArgs),
60    }
61}
62
63/// Extracts the generic args of `ty`, additionally validates it is of generic type `T`.
64fn extract_type_generic_args<T: NamedType>(
65    context: &dyn TypeSpecializationContext,
66    ty: &ConcreteTypeId,
67) -> Result<Vec<GenericArg>, SpecializationError> {
68    let long_id = context.get_type_info(ty.clone())?.long_id;
69    if long_id.generic_id != T::ID {
70        Err(SpecializationError::UnsupportedGenericArg)
71    } else {
72        Ok(long_id.generic_args)
73    }
74}
75
76#[cfg(test)]
77mod test;