cairo_lang_sierra/extensions/modules/
duplicate.rs

1use crate::extensions::lib_func::{
2    LibfuncSignature, OutputVarInfo, ParamSignature, SierraApChange, SignatureOnlyGenericLibfunc,
3    SignatureSpecializationContext,
4};
5use crate::extensions::{OutputVarReferenceInfo, SpecializationError, args_as_single_type};
6use crate::program::GenericArg;
7
8/// Libfunc for duplicating an object.
9#[derive(Default)]
10pub struct DupLibfunc {}
11impl SignatureOnlyGenericLibfunc for DupLibfunc {
12    const STR_ID: &'static str = "dup";
13
14    fn specialize_signature(
15        &self,
16        context: &dyn SignatureSpecializationContext,
17        generic_args: &[GenericArg],
18    ) -> Result<LibfuncSignature, SpecializationError> {
19        let ty = args_as_single_type(generic_args)?;
20        let info = context.get_type_info(ty.clone())?;
21        if !info.duplicatable {
22            return Err(SpecializationError::UnsupportedGenericArg);
23        }
24
25        let output_info = OutputVarInfo {
26            ty: ty.clone(),
27            ref_info: OutputVarReferenceInfo::SameAsParam { param_idx: 0 },
28        };
29        Ok(LibfuncSignature::new_non_branch_ex(
30            vec![ParamSignature::new(ty).with_allow_const()],
31            vec![output_info.clone(), output_info],
32            SierraApChange::Known { new_vars_only: true },
33        ))
34    }
35}