cairo_lang_sierra/extensions/
mod.rs

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/// Module for the set of core extensions.
pub mod core;
pub mod error;
pub mod lib_func;
/// All implementations of basic extensions are under this module.
pub mod modules;
pub mod type_specialization_context;
pub mod types;

use num_bigint::BigInt;

pub use self::error::{ExtensionError, SpecializationError};
pub use self::lib_func::{
    ConcreteLibfunc, GenericLibfunc, GenericLibfuncEx, NamedLibfunc, NoGenericArgsGenericLibfunc,
    OutputVarReferenceInfo, SignatureBasedConcreteLibfunc,
};
pub use self::modules::*;
use self::type_specialization_context::TypeSpecializationContext;
pub use self::types::{
    ConcreteType, GenericType, GenericTypeEx, NamedType, NoGenericArgsGenericType,
};
use crate::ids::{ConcreteTypeId, FunctionId};
use crate::program::GenericArg;

/// Helper for extracting the value from the template arguments.
fn args_as_single_value(args: &[GenericArg]) -> Result<BigInt, SpecializationError> {
    match args {
        [GenericArg::Value(c)] => Ok(c.clone()),
        [_] => Err(SpecializationError::UnsupportedGenericArg),
        _ => Err(SpecializationError::WrongNumberOfGenericArgs),
    }
}

/// Helper for extracting the type from the template arguments.
pub fn args_as_single_type(args: &[GenericArg]) -> Result<ConcreteTypeId, SpecializationError> {
    match args {
        [GenericArg::Type(ty)] => Ok(ty.clone()),
        [_] => Err(SpecializationError::UnsupportedGenericArg),
        _ => Err(SpecializationError::WrongNumberOfGenericArgs),
    }
}

/// Helper for extracting two types from the template arguments.
fn args_as_two_types(
    args: &[GenericArg],
) -> Result<(ConcreteTypeId, ConcreteTypeId), SpecializationError> {
    match args {
        [GenericArg::Type(ty0), GenericArg::Type(ty1)] => Ok((ty0.clone(), ty1.clone())),
        [_, _] => Err(SpecializationError::UnsupportedGenericArg),
        _ => Err(SpecializationError::WrongNumberOfGenericArgs),
    }
}

/// Helper for extracting the type from the template arguments.
fn args_as_single_user_func(args: &[GenericArg]) -> Result<FunctionId, SpecializationError> {
    match args {
        [GenericArg::UserFunc(function_id)] => Ok(function_id.clone()),
        [_] => Err(SpecializationError::UnsupportedGenericArg),
        _ => Err(SpecializationError::WrongNumberOfGenericArgs),
    }
}

/// Extracts the generic args of `ty`, additionally validates it is of generic type `T`.
fn extract_type_generic_args<T: NamedType>(
    context: &dyn TypeSpecializationContext,
    ty: &ConcreteTypeId,
) -> Result<Vec<GenericArg>, SpecializationError> {
    let long_id = context.get_type_info(ty.clone())?.long_id;
    if long_id.generic_id != T::ID {
        Err(SpecializationError::UnsupportedGenericArg)
    } else {
        Ok(long_id.generic_args)
    }
}

#[cfg(test)]
mod test;