diff --git a/crates/cairo-lang-lowering/src/cache/mod.rs b/crates/cairo-lang-lowering/src/cache/mod.rs index 16eed8ba09a..233cf4f49ce 100644 --- a/crates/cairo-lang-lowering/src/cache/mod.rs +++ b/crates/cairo-lang-lowering/src/cache/mod.rs @@ -54,8 +54,8 @@ use crate::objects::{ }; use crate::{ Block, BlockEnd, Location, Lowered, MatchArm, MatchEnumInfo, MatchEnumValue, MatchInfo, - StatementDesnap, StatementEnumConstruct, StatementSnapshot, StatementStructConstruct, - VarRemapping, VarUsage, Variable, + StatementDesnap, StatementEnumConstruct, StatementIntoBox, StatementSnapshot, + StatementStructConstruct, VarRemapping, VarUsage, Variable, }; type LookupCache = (CacheLookups, Vec<(DefsFunctionWithBodyIdCached, MultiLoweringCached)>); @@ -909,6 +909,9 @@ enum StatementCached { // Enums. EnumConstruct(StatementEnumConstructCached), + // Boxing. + IntoBox(StatementIntoBoxCached), + Snapshot(StatementSnapshotCached), Desnap(StatementDesnapCached), } @@ -933,6 +936,9 @@ impl StatementCached { Statement::Desnap(stmt) => { StatementCached::Desnap(StatementDesnapCached::new(stmt, ctx)) } + Statement::IntoBox(stmt) => { + StatementCached::IntoBox(StatementIntoBoxCached::new(stmt, ctx)) + } } } fn embed<'db>(self, ctx: &mut CacheLoadingContext<'db>) -> Statement<'db> { @@ -946,6 +952,7 @@ impl StatementCached { StatementCached::EnumConstruct(stmt) => Statement::EnumConstruct(stmt.embed(ctx)), StatementCached::Snapshot(stmt) => Statement::Snapshot(stmt.embed(ctx)), StatementCached::Desnap(stmt) => Statement::Desnap(stmt.embed(ctx)), + StatementCached::IntoBox(stmt) => Statement::IntoBox(stmt.embed(ctx)), } } } @@ -1246,6 +1253,23 @@ impl StatementDesnapCached { } } +#[derive(Serialize, Deserialize)] +struct StatementIntoBoxCached { + input: VarUsageCached, + output: usize, +} +impl StatementIntoBoxCached { + fn new<'db>(stmt: StatementIntoBox<'db>, ctx: &mut CacheSavingContext<'db>) -> Self { + Self { input: VarUsageCached::new(stmt.input, ctx), output: stmt.output.index() } + } + fn embed<'db>(self, ctx: &mut CacheLoadingContext<'db>) -> StatementIntoBox<'db> { + StatementIntoBox { + input: self.input.embed(ctx), + output: ctx.lowered_variables_id[self.output], + } + } +} + #[derive(Serialize, Deserialize, Clone)] struct LocationCached { /// The stable location of the object. diff --git a/crates/cairo-lang-lowering/src/concretize/mod.rs b/crates/cairo-lang-lowering/src/concretize/mod.rs index 771c3efd2ba..229af6f7c72 100644 --- a/crates/cairo-lang-lowering/src/concretize/mod.rs +++ b/crates/cairo-lang-lowering/src/concretize/mod.rs @@ -62,7 +62,8 @@ pub fn concretize_lowered<'db>( Statement::Snapshot(_) | Statement::Desnap(_) | Statement::StructConstruct(_) - | Statement::StructDestructure(_) => {} + | Statement::StructDestructure(_) + | Statement::IntoBox(_) => {} } } if let BlockEnd::Match { info } = &mut block.end { diff --git a/crates/cairo-lang-lowering/src/fmt.rs b/crates/cairo-lang-lowering/src/fmt.rs index 318611edf37..764435a4b6d 100644 --- a/crates/cairo-lang-lowering/src/fmt.rs +++ b/crates/cairo-lang-lowering/src/fmt.rs @@ -5,8 +5,8 @@ use itertools::Itertools; use salsa::Database; use crate::objects::{ - MatchExternInfo, Statement, StatementCall, StatementConst, StatementStructDestructure, - VariableId, + MatchExternInfo, Statement, StatementCall, StatementConst, StatementIntoBox, + StatementStructDestructure, VariableId, }; use crate::{ Block, BlockEnd, Lowered, MatchArm, MatchEnumInfo, MatchEnumValue, MatchInfo, StatementDesnap, @@ -188,6 +188,7 @@ impl<'db> DebugWithDb<'db> for Statement<'db> { Statement::EnumConstruct(stmt) => stmt.fmt(f, ctx), Statement::Snapshot(stmt) => stmt.fmt(f, ctx), Statement::Desnap(stmt) => stmt.fmt(f, ctx), + Statement::IntoBox(stmt) => stmt.fmt(f, ctx), } } } @@ -365,3 +366,13 @@ impl<'db> DebugWithDb<'db> for StatementDesnap<'db> { write!(f, ")") } } + +impl<'db> DebugWithDb<'db> for StatementIntoBox<'db> { + type Db = LoweredFormatter<'db>; + + fn fmt(&self, f: &mut std::fmt::Formatter<'_>, ctx: &Self::Db) -> std::fmt::Result { + write!(f, "into_box(")?; + self.input.fmt(f, ctx)?; + write!(f, ")") + } +} diff --git a/crates/cairo-lang-lowering/src/lower/generators.rs b/crates/cairo-lang-lowering/src/lower/generators.rs index 0fb51c9868d..2861006f543 100644 --- a/crates/cairo-lang-lowering/src/lower/generators.rs +++ b/crates/cairo-lang-lowering/src/lower/generators.rs @@ -3,6 +3,7 @@ use cairo_lang_semantic as semantic; use cairo_lang_semantic::ConcreteVariant; +use cairo_lang_semantic::corelib::core_box_ty; use cairo_lang_semantic::items::constant::ConstValueId; use cairo_lang_utils::{Intern, extract_matches}; use itertools::chain; @@ -15,7 +16,7 @@ use crate::objects::{ Statement, StatementCall, StatementConst, StatementStructConstruct, StatementStructDestructure, VarUsage, }; -use crate::{StatementDesnap, StatementEnumConstruct, StatementSnapshot}; +use crate::{StatementDesnap, StatementEnumConstruct, StatementIntoBox, StatementSnapshot}; #[derive(Clone, Default)] pub struct StatementsBuilder<'db> { @@ -256,3 +257,22 @@ impl<'db> StructConstruct<'db> { VarUsage { var_id: output, location: self.location } } } + +/// Generator for [StatementIntoBox]. +pub struct IntoBox<'db> { + pub input: VarUsage<'db>, + pub location: LocationId<'db>, +} +impl<'db> IntoBox<'db> { + pub fn add( + self, + ctx: &mut LoweringContext<'db, '_>, + builder: &mut StatementsBuilder<'db>, + ) -> VarUsage<'db> { + let input_ty = ctx.variables[self.input.var_id].ty; + let output_ty = core_box_ty(ctx.db, input_ty); + let output = ctx.new_var(VarRequest { ty: output_ty, location: self.location }); + builder.push_statement(Statement::IntoBox(StatementIntoBox { input: self.input, output })); + VarUsage { var_id: output, location: self.location } + } +} diff --git a/crates/cairo-lang-lowering/src/lower/mod.rs b/crates/cairo-lang-lowering/src/lower/mod.rs index c6af7fcc6b7..6d6bd205dd8 100644 --- a/crates/cairo-lang-lowering/src/lower/mod.rs +++ b/crates/cairo-lang-lowering/src/lower/mod.rs @@ -1351,7 +1351,7 @@ fn perform_function_call<'db>( function_call_info; // If the function is not extern, simply call it. - if function.try_get_extern_function_id(ctx.db).is_none() { + let Some(extern_function_id) = function.try_get_extern_function_id(ctx.db) else { let call_result = generators::Call { function: function.lowered(ctx.db), inputs, @@ -1390,6 +1390,16 @@ fn perform_function_call<'db>( // Extern function. assert!(coupon_input.is_none(), "Extern functions cannot have a __coupon__ argument."); + + // Handle into_box specially - emit IntoBox instead of a call. + let info = ctx.db.core_info(); + if extern_function_id == info.into_box { + assert!(extra_ret_tys.is_empty(), "into_box should not have extra return types"); + let input = inputs.into_iter().exactly_one().expect("into_box expects exactly one input"); + let res = generators::IntoBox { input, location }.add(ctx, &mut builder.statements); + return Ok((vec![], LoweredExpr::AtVariable(res))); + } + let ret_tys = extern_facade_return_tys(ctx, ret_ty); let call_result = generators::Call { function: function.lowered(ctx.db), diff --git a/crates/cairo-lang-lowering/src/objects.rs b/crates/cairo-lang-lowering/src/objects.rs index 7f785589731..3d50093b4f3 100644 --- a/crates/cairo-lang-lowering/src/objects.rs +++ b/crates/cairo-lang-lowering/src/objects.rs @@ -294,6 +294,9 @@ pub enum Statement<'db> { Snapshot(StatementSnapshot<'db>), Desnap(StatementDesnap<'db>), + + // Boxing. + IntoBox(StatementIntoBox<'db>), } impl<'db> Statement<'db> { pub fn inputs(&self) -> &[VarUsage<'db>] { @@ -305,6 +308,7 @@ impl<'db> Statement<'db> { Statement::EnumConstruct(stmt) => std::slice::from_ref(&stmt.input), Statement::Snapshot(stmt) => std::slice::from_ref(&stmt.input), Statement::Desnap(stmt) => std::slice::from_ref(&stmt.input), + Statement::IntoBox(stmt) => std::slice::from_ref(&stmt.input), } } @@ -317,6 +321,7 @@ impl<'db> Statement<'db> { Statement::EnumConstruct(stmt) => std::slice::from_mut(&mut stmt.input), Statement::Snapshot(stmt) => std::slice::from_mut(&mut stmt.input), Statement::Desnap(stmt) => std::slice::from_mut(&mut stmt.input), + Statement::IntoBox(stmt) => std::slice::from_mut(&mut stmt.input), } } @@ -329,6 +334,7 @@ impl<'db> Statement<'db> { Statement::EnumConstruct(stmt) => std::slice::from_ref(&stmt.output), Statement::Snapshot(stmt) => stmt.outputs.as_slice(), Statement::Desnap(stmt) => std::slice::from_ref(&stmt.output), + Statement::IntoBox(stmt) => std::slice::from_ref(&stmt.output), } } @@ -341,6 +347,7 @@ impl<'db> Statement<'db> { Statement::EnumConstruct(stmt) => std::slice::from_mut(&mut stmt.output), Statement::Snapshot(stmt) => stmt.outputs.as_mut_slice(), Statement::Desnap(stmt) => std::slice::from_mut(&mut stmt.output), + Statement::IntoBox(stmt) => std::slice::from_mut(&mut stmt.output), } } pub fn location(&self) -> Option> { @@ -353,6 +360,7 @@ impl<'db> Statement<'db> { Statement::EnumConstruct(stmt) => Some(stmt.input.location), Statement::Snapshot(stmt) => Some(stmt.input.location), Statement::Desnap(stmt) => Some(stmt.input.location), + Statement::IntoBox(stmt) => Some(stmt.input.location), } } pub fn location_mut(&mut self) -> Option<&mut LocationId<'db>> { @@ -364,6 +372,7 @@ impl<'db> Statement<'db> { Statement::EnumConstruct(stmt) => Some(&mut stmt.input.location), Statement::Snapshot(stmt) => Some(&mut stmt.input.location), Statement::Desnap(stmt) => Some(&mut stmt.input.location), + Statement::IntoBox(stmt) => Some(&mut stmt.input.location), } } } @@ -470,6 +479,15 @@ pub struct StatementDesnap<'db> { pub output: VariableId, } +/// A statement that constructs a box from a value. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct StatementIntoBox<'db> { + /// The value to box. + pub input: VarUsage<'db>, + /// The variable to bind the boxed value to. + pub output: VariableId, +} + /// An arm of a match statement. #[derive(Clone, Debug, PartialEq, Eq)] pub struct MatchArm<'db> { diff --git a/crates/cairo-lang-lowering/src/optimizations/config.rs b/crates/cairo-lang-lowering/src/optimizations/config.rs index a259adde109..b5dc952eddf 100644 --- a/crates/cairo-lang-lowering/src/optimizations/config.rs +++ b/crates/cairo-lang-lowering/src/optimizations/config.rs @@ -108,7 +108,7 @@ fn default_moveable_functions() -> Vec { ["bool_not_impl"], ["felt252_add", "felt252_sub", "felt252_mul", "felt252_div"], ["array::array_new", "array::array_append"], - ["box::unbox", "box::box_forward_snapshot", "box::into_box"], + ["box::unbox", "box::box_forward_snapshot"], ) .map(|s| s.to_string()) .collect(); diff --git a/crates/cairo-lang-lowering/src/optimizations/const_folding.rs b/crates/cairo-lang-lowering/src/optimizations/const_folding.rs index 603e648d3fe..da4fcf1dfd6 100644 --- a/crates/cairo-lang-lowering/src/optimizations/const_folding.rs +++ b/crates/cairo-lang-lowering/src/optimizations/const_folding.rs @@ -43,7 +43,7 @@ use crate::utils::InliningStrategy; use crate::{ Block, BlockEnd, BlockId, DependencyType, Lowered, LoweringStage, MatchArm, MatchEnumInfo, MatchExternInfo, MatchInfo, Statement, StatementCall, StatementConst, StatementDesnap, - StatementEnumConstruct, StatementSnapshot, StatementStructConstruct, + StatementEnumConstruct, StatementIntoBox, StatementSnapshot, StatementStructConstruct, StatementStructDestructure, VarRemapping, VarUsage, Variable, VariableArena, VariableId, }; @@ -337,6 +337,25 @@ impl<'db, 'mt> ConstFoldingContext<'db, 'mt> { }; self.var_info.insert(*output, value); } + Statement::IntoBox(StatementIntoBox { input, output }) => { + let var_info = self.var_info.get(&input.var_id); + let const_value = match var_info { + Some(VarInfo::Const(val)) => Some(*val), + Some(VarInfo::Snapshot(info)) => { + try_extract_matches!(info.as_ref(), VarInfo::Const).copied() + } + _ => None, + }; + let var_info = + var_info.cloned().or_else(|| var_info_if_copy(self.variables, *input)); + if let Some(var_info) = var_info { + self.var_info.insert(*output, VarInfo::Box(var_info.into())); + } + + if let Some(const_value) = const_value { + *stmt = Statement::Const(StatementConst::new_boxed(const_value, *output)); + } + } } } @@ -630,19 +649,6 @@ impl<'db, 'mt> ConstFoldingContext<'db, 'mt> { self.storage_base_address_const.concretize(db, vec![arg]).lowered(db); } None - } else if id == self.into_box { - let input = stmt.inputs[0]; - let var_info = self.var_info.get(&input.var_id); - let const_value = match var_info { - Some(VarInfo::Const(val)) => Some(*val), - Some(VarInfo::Snapshot(info)) => { - try_extract_matches!(info.as_ref(), VarInfo::Const).copied() - } - _ => None, - }; - let var_info = var_info.cloned().or_else(|| var_info_if_copy(self.variables, input))?; - self.var_info.insert(stmt.outputs[0], VarInfo::Box(var_info.into())); - Some(Statement::Const(StatementConst::new_boxed(const_value?, stmt.outputs[0]))) } else if id == self.unbox { if let VarInfo::Box(inner) = self.var_info.get(&stmt.inputs[0].var_id)? { let inner = inner.as_ref().clone(); @@ -1467,8 +1473,6 @@ pub struct ConstFoldingLibfuncInfo<'db> { felt_mul: ExternFunctionId<'db>, /// The `felt252_div` libfunc. felt_div: ExternFunctionId<'db>, - /// The `into_box` libfunc. - into_box: ExternFunctionId<'db>, /// The `unbox` libfunc. unbox: ExternFunctionId<'db>, /// The `box_forward_snapshot` libfunc. @@ -1627,7 +1631,6 @@ impl<'db> ConstFoldingLibfuncInfo<'db> { felt_add: core.extern_function_id("felt252_add"), felt_mul: core.extern_function_id("felt252_mul"), felt_div: core.extern_function_id("felt252_div"), - into_box: box_module.extern_function_id("into_box"), unbox: box_module.extern_function_id("unbox"), box_forward_snapshot: box_module.generic_function_id("box_forward_snapshot"), eq_fns, diff --git a/crates/cairo-lang-lowering/src/optimizations/dedup_blocks.rs b/crates/cairo-lang-lowering/src/optimizations/dedup_blocks.rs index 0e1cf74f135..c4b817b6dfe 100644 --- a/crates/cairo-lang-lowering/src/optimizations/dedup_blocks.rs +++ b/crates/cairo-lang-lowering/src/optimizations/dedup_blocks.rs @@ -12,7 +12,7 @@ use crate::ids::FunctionId; use crate::utils::{Rebuilder, RebuilderEx}; use crate::{ Block, BlockEnd, BlockId, Lowered, Statement, StatementCall, StatementConst, StatementDesnap, - StatementEnumConstruct, StatementSnapshot, StatementStructConstruct, + StatementEnumConstruct, StatementIntoBox, StatementSnapshot, StatementStructConstruct, StatementStructDestructure, VarRemapping, VarUsage, VariableArena, VariableId, }; @@ -59,7 +59,10 @@ enum CanonicStatement<'db> { input: CanonicVar, output: CanonicVar, }, - + IntoBox { + input: CanonicVar, + output: CanonicVar, + }, Snapshot { input: CanonicVar, outputs: [CanonicVar; 2], @@ -163,6 +166,10 @@ impl<'db, 'a> CanonicBlockBuilder<'db, 'a> { input: self.handle_input(input), output: self.handle_output(output), }, + Statement::IntoBox(StatementIntoBox { input, output }) => CanonicStatement::IntoBox { + input: self.handle_input(input), + output: self.handle_output(output), + }, } } } diff --git a/crates/cairo-lang-lowering/src/optimizations/test_data/const_folding b/crates/cairo-lang-lowering/src/optimizations/test_data/const_folding index 601ee86a3fd..bd0b8310659 100644 --- a/crates/cairo-lang-lowering/src/optimizations/test_data/const_folding +++ b/crates/cairo-lang-lowering/src/optimizations/test_data/const_folding @@ -229,7 +229,7 @@ Parameters: blk0 (root): Statements: (v0: core::felt252) <- 0 - (v1: core::box::Box::) <- core::box::into_box::(v0) + (v1: core::box::Box::) <- into_box(v0) End: Return(v1) @@ -271,7 +271,7 @@ blk0 (root): Statements: (v0: core::felt252) <- 1 (v1: test::A) <- struct_construct(v0) - (v2: core::box::Box::) <- core::box::into_box::(v1) + (v2: core::box::Box::) <- into_box(v1) End: Return(v2) @@ -310,7 +310,7 @@ blk0 (root): Statements: (v0: core::felt252) <- 2 (v1: core::option::Option::) <- Option::Some(v0) - (v2: core::box::Box::>) <- core::box::into_box::>(v1) + (v2: core::box::Box::>) <- into_box(v1) End: Return(v2) @@ -348,7 +348,7 @@ Parameters: blk0 (root): Statements: (v0: core::felt252) <- 2 - (v1: core::box::Box::) <- core::box::into_box::(v0) + (v1: core::box::Box::) <- into_box(v0) (v2: core::felt252) <- core::box::unbox::(v1) End: Return(v2) @@ -3795,14 +3795,14 @@ End: blk1: Statements: - (v3: core::box::Box::>>) <- core::box::into_box::>>(v1) + (v3: core::box::Box::>>) <- into_box(v1) (v4: core::result::Result::>>, core::box::Box::>>>) <- Result::Ok(v3) End: Goto(blk3, {v4 -> v5}) blk2: Statements: - (v6: core::box::Box::>>) <- core::box::into_box::>>(v2) + (v6: core::box::Box::>>) <- into_box(v2) (v7: core::result::Result::>>, core::box::Box::>>>) <- Result::Err(v6) End: Goto(blk3, {v7 -> v5}) @@ -3830,7 +3830,7 @@ End: blk2: Statements: - (v6: core::box::Box::>>) <- core::box::into_box::>>(v2) + (v6: core::box::Box::>>) <- into_box(v2) (v7: core::result::Result::>>, core::box::Box::>>>) <- Result::Err(v6) End: Goto(blk3, {v7 -> v5}) @@ -3880,14 +3880,14 @@ End: blk1: Statements: - (v3: core::box::Box::>>) <- core::box::into_box::>>(v1) + (v3: core::box::Box::>>) <- into_box(v1) (v4: core::result::Result::>>, core::box::Box::>>>) <- Result::Ok(v3) End: Goto(blk3, {v4 -> v5}) blk2: Statements: - (v6: core::box::Box::>>) <- core::box::into_box::>>(v2) + (v6: core::box::Box::>>) <- into_box(v2) (v7: core::result::Result::>>, core::box::Box::>>>) <- Result::Err(v6) End: Goto(blk3, {v7 -> v5}) @@ -3908,7 +3908,7 @@ End: blk1: Statements: - (v3: core::box::Box::>>) <- core::box::into_box::>>(v1) + (v3: core::box::Box::>>) <- into_box(v1) (v4: core::result::Result::>>, core::box::Box::>>>) <- Result::Ok(v3) End: Goto(blk3, {v4 -> v5}) diff --git a/crates/cairo-lang-lowering/src/optimizations/test_data/reboxing b/crates/cairo-lang-lowering/src/optimizations/test_data/reboxing index 71246bc5ea4..46d7a69b376 100644 --- a/crates/cairo-lang-lowering/src/optimizations/test_data/reboxing +++ b/crates/cairo-lang-lowering/src/optimizations/test_data/reboxing @@ -23,7 +23,6 @@ fn main(a: Box) -> Box { //! > lowering_diagnostics //! > candidates -v4 //! > before Parameters: v0: core::box::Box:: @@ -31,7 +30,7 @@ blk0 (root): Statements: (v1: test::A) <- core::box::unbox::(v0) (v2: core::felt252, v3: core::felt252) <- struct_destructure(v1) - (v4: core::box::Box::) <- core::box::into_box::(v3) + (v4: core::box::Box::) <- into_box(v3) End: Return(v4) @@ -41,7 +40,7 @@ blk0 (root): Statements: (v1: test::A) <- core::box::unbox::(v0) (v2: core::felt252, v3: core::felt252) <- struct_destructure(v1) - (v5: core::box::Box::, v4: core::box::Box::) <- struct_destructure(v0) + (v4: core::box::Box::) <- into_box(v3) End: Return(v4) @@ -75,7 +74,6 @@ fn multi_member(p: Box) -> (Box, Box) { //! > lowering_diagnostics //! > candidates -v5, v10 //! > before Parameters: v0: core::box::Box:: @@ -83,10 +81,10 @@ blk0 (root): Statements: (v1: test::Point) <- core::box::unbox::(v0) (v2: core::integer::u32, v3: core::integer::u32, v4: core::integer::u32) <- struct_destructure(v1) - (v5: core::box::Box::) <- core::box::into_box::(v2) + (v5: core::box::Box::) <- into_box(v2) (v6: test::Point) <- core::box::unbox::(v0) (v7: core::integer::u32, v8: core::integer::u32, v9: core::integer::u32) <- struct_destructure(v6) - (v10: core::box::Box::) <- core::box::into_box::(v9) + (v10: core::box::Box::) <- into_box(v9) (v11: (core::box::Box::, core::box::Box::)) <- struct_construct(v5, v10) End: Return(v11) @@ -97,10 +95,10 @@ blk0 (root): Statements: (v1: test::Point) <- core::box::unbox::(v0) (v2: core::integer::u32, v3: core::integer::u32, v4: core::integer::u32) <- struct_destructure(v1) - (v5: core::box::Box::, v12: core::box::Box::, v13: core::box::Box::) <- struct_destructure(v0) + (v5: core::box::Box::) <- into_box(v2) (v6: test::Point) <- core::box::unbox::(v0) (v7: core::integer::u32, v8: core::integer::u32, v9: core::integer::u32) <- struct_destructure(v6) - (v14: core::box::Box::, v15: core::box::Box::, v10: core::box::Box::) <- struct_destructure(v0) + (v10: core::box::Box::) <- into_box(v9) (v11: (core::box::Box::, core::box::Box::)) <- struct_construct(v5, v10) End: Return(v11) @@ -139,7 +137,6 @@ fn nested_struct(o: Box) -> Box { //! > lowering_diagnostics //! > candidates -v5 //! > before Parameters: v0: core::box::Box:: @@ -148,7 +145,7 @@ Statements: (v1: test::Outer) <- core::box::unbox::(v0) (v2: test::Inner, v3: core::felt252) <- struct_destructure(v1) (v4: core::felt252) <- struct_destructure(v2) - (v5: core::box::Box::) <- core::box::into_box::(v4) + (v5: core::box::Box::) <- into_box(v4) End: Return(v5) @@ -159,7 +156,7 @@ Statements: (v1: test::Outer) <- core::box::unbox::(v0) (v2: test::Inner, v3: core::felt252) <- struct_destructure(v1) (v4: core::felt252) <- struct_destructure(v2) - (v5: core::box::Box::) <- core::box::into_box::(v4) + (v5: core::box::Box::) <- into_box(v4) End: Return(v5) @@ -197,7 +194,6 @@ fn with_snapshot(data: Box<@Data>) -> Box<@NonCopy> { //! > lowering_diagnostics //! > candidates -v4 //! > before Parameters: v0: core::box::Box::<@test::Data> @@ -205,7 +201,7 @@ blk0 (root): Statements: (v1: @test::Data) <- core::box::unbox::<@test::Data>(v0) (v2: @test::NonCopy, v3: @core::felt252) <- struct_destructure(v1) - (v4: core::box::Box::<@test::NonCopy>) <- core::box::into_box::<@test::NonCopy>(v2) + (v4: core::box::Box::<@test::NonCopy>) <- into_box(v2) End: Return(v4) @@ -215,7 +211,7 @@ blk0 (root): Statements: (v1: @test::Data) <- core::box::unbox::<@test::Data>(v0) (v2: @test::NonCopy, v3: @core::felt252) <- struct_destructure(v1) - (v4: core::box::Box::<@test::NonCopy>, v5: core::box::Box::<@core::felt252>) <- struct_destructure(v0) + (v4: core::box::Box::<@test::NonCopy>) <- into_box(v2) End: Return(v4) @@ -244,14 +240,13 @@ fn rebox_whole(s: Box) -> Box { //! > lowering_diagnostics //! > candidates -v2 //! > before Parameters: v0: core::box::Box:: blk0 (root): Statements: (v1: test::Simple) <- core::box::unbox::(v0) - (v2: core::box::Box::) <- core::box::into_box::(v1) + (v2: core::box::Box::) <- into_box(v1) End: Return(v2) @@ -260,8 +255,9 @@ Parameters: v0: core::box::Box:: blk0 (root): Statements: (v1: test::Simple) <- core::box::unbox::(v0) + (v2: core::box::Box::) <- into_box(v1) End: - Return(v0) + Return(v2) //! > ========================================================================== @@ -296,7 +292,7 @@ fn no_opportunity(d: Box, x: felt252) -> Box { Parameters: v0: core::box::Box::, v1: core::felt252 blk0 (root): Statements: - (v5: core::box::Box::) <- core::box::into_box::(v1) + (v5: core::box::Box::) <- into_box(v1) End: Return(v5) @@ -304,7 +300,7 @@ End: Parameters: v0: core::box::Box::, v1: core::felt252 blk0 (root): Statements: - (v5: core::box::Box::) <- core::box::into_box::(v1) + (v5: core::box::Box::) <- into_box(v1) End: Return(v5) @@ -363,7 +359,7 @@ End: blk3: Statements: - (v5: core::box::Box::) <- core::box::into_box::(v4) + (v5: core::box::Box::) <- into_box(v4) End: Return(v5) @@ -390,7 +386,7 @@ End: blk3: Statements: - (v5: core::box::Box::) <- core::box::into_box::(v4) + (v5: core::box::Box::) <- into_box(v4) End: Return(v5) @@ -417,7 +413,6 @@ fn tuple_rebox(t: Box<(u32, felt252, u64)>) -> Box { //! > lowering_diagnostics //! > candidates -v5 //! > before Parameters: v0: core::box::Box::<(core::integer::u32, core::felt252, core::integer::u64)> @@ -425,7 +420,7 @@ blk0 (root): Statements: (v1: (core::integer::u32, core::felt252, core::integer::u64)) <- core::box::unbox::<(core::integer::u32, core::felt252, core::integer::u64)>(v0) (v2: core::integer::u32, v3: core::felt252, v4: core::integer::u64) <- struct_destructure(v1) - (v5: core::box::Box::) <- core::box::into_box::(v3) + (v5: core::box::Box::) <- into_box(v3) End: Return(v5) @@ -435,7 +430,7 @@ blk0 (root): Statements: (v1: (core::integer::u32, core::felt252, core::integer::u64)) <- core::box::unbox::<(core::integer::u32, core::felt252, core::integer::u64)>(v0) (v2: core::integer::u32, v3: core::felt252, v4: core::integer::u64) <- struct_destructure(v1) - (v6: core::box::Box::, v5: core::box::Box::, v7: core::box::Box::) <- struct_destructure(v0) + (v5: core::box::Box::) <- into_box(v3) End: Return(v5) @@ -468,7 +463,6 @@ fn non_copy_struct_rebox(s: Box) -> Box { //! > lowering_diagnostics //! > candidates -v4 //! > before Parameters: v0: core::box::Box:: @@ -476,7 +470,7 @@ blk0 (root): Statements: (v1: test::NonCopyStruct) <- core::box::unbox::(v0) (v2: core::array::Array::, v3: core::felt252) <- struct_destructure(v1) - (v4: core::box::Box::) <- core::box::into_box::(v3) + (v4: core::box::Box::) <- into_box(v3) End: Return(v4) @@ -486,7 +480,7 @@ blk0 (root): Statements: (v1: test::NonCopyStruct) <- core::box::unbox::(v0) (v2: core::array::Array::, v3: core::felt252) <- struct_destructure(v1) - (v4: core::box::Box::) <- core::box::into_box::(v3) + (v4: core::box::Box::) <- into_box(v3) End: Return(v4) @@ -513,7 +507,6 @@ fn non_copy_tuple_rebox(t: Box<(Array, felt252)>) -> Box { //! > lowering_diagnostics //! > candidates -v4 //! > before Parameters: v0: core::box::Box::<(core::array::Array::, core::felt252)> @@ -521,7 +514,7 @@ blk0 (root): Statements: (v1: (core::array::Array::, core::felt252)) <- core::box::unbox::<(core::array::Array::, core::felt252)>(v0) (v2: core::array::Array::, v3: core::felt252) <- struct_destructure(v1) - (v4: core::box::Box::) <- core::box::into_box::(v3) + (v4: core::box::Box::) <- into_box(v3) End: Return(v4) @@ -531,7 +524,7 @@ blk0 (root): Statements: (v1: (core::array::Array::, core::felt252)) <- core::box::unbox::<(core::array::Array::, core::felt252)>(v0) (v2: core::array::Array::, v3: core::felt252) <- struct_destructure(v1) - (v4: core::box::Box::) <- core::box::into_box::(v3) + (v4: core::box::Box::) <- into_box(v3) End: Return(v4) @@ -596,7 +589,7 @@ End: blk3: Statements: (v9: core::felt252, v10: core::felt252) <- struct_destructure(v7) - (v11: core::box::Box::) <- core::box::into_box::(v10) + (v11: core::box::Box::) <- into_box(v10) End: Return(v11) @@ -625,7 +618,7 @@ End: blk3: Statements: (v9: core::felt252, v10: core::felt252) <- struct_destructure(v7) - (v11: core::box::Box::) <- core::box::into_box::(v10) + (v11: core::box::Box::) <- into_box(v10) End: Return(v11) @@ -664,7 +657,6 @@ fn main(a: Box) -> (Box, NonDrop) { //! > lowering_diagnostics //! > candidates -v4 //! > before Parameters: v0: core::box::Box:: @@ -672,7 +664,7 @@ blk0 (root): Statements: (v1: test::A) <- core::box::unbox::(v0) (v2: core::felt252, v3: test::NonDrop) <- struct_destructure(v1) - (v4: core::box::Box::) <- core::box::into_box::(v2) + (v4: core::box::Box::) <- into_box(v2) (v5: (core::box::Box::, test::NonDrop)) <- struct_construct(v4, v3) End: Return(v5) @@ -683,7 +675,7 @@ blk0 (root): Statements: (v1: test::A) <- core::box::unbox::(v0) (v2: core::felt252, v3: test::NonDrop) <- struct_destructure(v1) - (v4: core::box::Box::) <- core::box::into_box::(v2) + (v4: core::box::Box::) <- into_box(v2) (v5: (core::box::Box::, test::NonDrop)) <- struct_construct(v4, v3) End: Return(v5) @@ -723,7 +715,6 @@ fn main(a: Box<@A>) -> (Box<@felt252>, @NonDrop) { //! > lowering_diagnostics //! > candidates -v4 //! > before Parameters: v0: core::box::Box::<@test::A> @@ -731,7 +722,7 @@ blk0 (root): Statements: (v1: @test::A) <- core::box::unbox::<@test::A>(v0) (v2: @core::felt252, v3: @test::NonDrop) <- struct_destructure(v1) - (v4: core::box::Box::<@core::felt252>) <- core::box::into_box::<@core::felt252>(v2) + (v4: core::box::Box::<@core::felt252>) <- into_box(v2) (v5: @core::felt252, v6: @test::NonDrop) <- struct_destructure(v1) (v7: (core::box::Box::<@core::felt252>, @test::NonDrop)) <- struct_construct(v4, v6) End: @@ -743,7 +734,7 @@ blk0 (root): Statements: (v1: @test::A) <- core::box::unbox::<@test::A>(v0) (v2: @core::felt252, v3: @test::NonDrop) <- struct_destructure(v1) - (v4: core::box::Box::<@core::felt252>, v8: core::box::Box::<@test::NonDrop>) <- struct_destructure(v0) + (v4: core::box::Box::<@core::felt252>) <- into_box(v2) (v5: @core::felt252, v6: @test::NonDrop) <- struct_destructure(v1) (v7: (core::box::Box::<@core::felt252>, @test::NonDrop)) <- struct_construct(v4, v6) End: @@ -760,6 +751,7 @@ test_reboxing_analysis mixed_reboxing //! > TODO(eytan-starkware): When removing demand for Copy, check no double + //! > into_box remain //! > module_code @@ -783,7 +775,6 @@ fn mixed_reboxing(p: Box, flag: bool) -> Box { } //! > candidates -v5, v9, v14 //! > before Parameters: v0: core::box::Box::, v1: core::bool @@ -798,10 +789,10 @@ End: blk1: Statements: (v4: test::Point) <- core::box::unbox::(v0) - (v5: core::box::Box::) <- core::box::into_box::(v4) + (v5: core::box::Box::) <- into_box(v4) (v6: test::Point) <- core::box::unbox::(v5) (v7: core::felt252, v8: core::felt252) <- struct_destructure(v6) - (v9: core::box::Box::) <- core::box::into_box::(v8) + (v9: core::box::Box::) <- into_box(v8) End: Goto(blk3, {v9 -> v10}) @@ -809,7 +800,7 @@ blk2: Statements: (v11: test::Point) <- core::box::unbox::(v0) (v12: core::felt252, v13: core::felt252) <- struct_destructure(v11) - (v14: core::box::Box::) <- core::box::into_box::(v12) + (v14: core::box::Box::) <- into_box(v12) End: Goto(blk3, {v14 -> v10}) @@ -831,9 +822,10 @@ End: blk1: Statements: (v4: test::Point) <- core::box::unbox::(v0) - (v6: test::Point) <- core::box::unbox::(v0) + (v5: core::box::Box::) <- into_box(v4) + (v6: test::Point) <- core::box::unbox::(v5) (v7: core::felt252, v8: core::felt252) <- struct_destructure(v6) - (v15: core::box::Box::, v9: core::box::Box::) <- struct_destructure(v0) + (v9: core::box::Box::) <- into_box(v8) End: Goto(blk3, {v9 -> v10}) @@ -841,7 +833,7 @@ blk2: Statements: (v11: test::Point) <- core::box::unbox::(v0) (v12: core::felt252, v13: core::felt252) <- struct_destructure(v11) - (v14: core::box::Box::, v16: core::box::Box::) <- struct_destructure(v0) + (v14: core::box::Box::) <- into_box(v12) End: Goto(blk3, {v14 -> v10}) diff --git a/crates/cairo-lang-lowering/src/test_data/repr_ptr b/crates/cairo-lang-lowering/src/test_data/repr_ptr index 785e23edd94..ca8e7af2ace 100644 --- a/crates/cairo-lang-lowering/src/test_data/repr_ptr +++ b/crates/cairo-lang-lowering/src/test_data/repr_ptr @@ -30,10 +30,10 @@ blk0 (root): Statements: (v1: core::integer::u32, v2: core::integer::u32) <- struct_destructure(v0) (v3: core::integer::u32, v4: @core::integer::u32) <- snapshot(v1) - (v5: core::box::Box::<@core::integer::u32>) <- core::box::into_box::<@core::integer::u32>(v4) + (v5: core::box::Box::<@core::integer::u32>) <- into_box(v4) () <- test::bar(v5) (v6: core::integer::u32, v7: @core::integer::u32) <- snapshot(v2) - (v8: core::box::Box::<@core::integer::u32>) <- core::box::into_box::<@core::integer::u32>(v7) + (v8: core::box::Box::<@core::integer::u32>) <- into_box(v7) () <- test::baz(v8) End: Return() @@ -67,10 +67,10 @@ blk0 (root): Statements: (v0: core::box::Box::<@core::integer::u32>) <- 3.into_box() (v1: core::box::Box::<@core::integer::u32>, v2: @core::box::Box::<@core::integer::u32>) <- snapshot(v0) - (v3: core::box::Box::<@core::box::Box::<@core::integer::u32>>) <- core::box::into_box::<@core::box::Box::<@core::integer::u32>>(v2) - (v4: core::box::Box::<@core::box::Box::<@core::integer::u32>>) <- core::box::into_box::<@core::box::Box::<@core::integer::u32>>(v2) + (v3: core::box::Box::<@core::box::Box::<@core::integer::u32>>) <- into_box(v2) + (v4: core::box::Box::<@core::box::Box::<@core::integer::u32>>) <- into_box(v2) (v5: core::box::Box::<@core::box::Box::<@core::integer::u32>>, v6: @core::box::Box::<@core::box::Box::<@core::integer::u32>>) <- snapshot(v4) - (v7: core::box::Box::<@core::box::Box::<@core::box::Box::<@core::integer::u32>>>) <- core::box::into_box::<@core::box::Box::<@core::box::Box::<@core::integer::u32>>>(v6) + (v7: core::box::Box::<@core::box::Box::<@core::box::Box::<@core::integer::u32>>>) <- into_box(v6) () <- test::bar(v0, v3, v7) End: Return() @@ -136,7 +136,7 @@ Parameters: v0: @core::integer::u32 blk0 (root): Statements: (v1: @core::integer::u32, v2: @@core::integer::u32) <- snapshot(v0) - (v3: core::box::Box::<@@core::integer::u32>) <- core::box::into_box::<@@core::integer::u32>(v2) + (v3: core::box::Box::<@@core::integer::u32>) <- into_box(v2) () <- test::bar(v3) End: Return() @@ -179,7 +179,7 @@ End: blk1: Statements: (v3: core::integer::u32, v4: @core::integer::u32) <- snapshot(v1) - (v5: core::box::Box::<@core::integer::u32>) <- core::box::into_box::<@core::integer::u32>(v4) + (v5: core::box::Box::<@core::integer::u32>) <- into_box(v4) () <- test::bar(v5) End: Return() diff --git a/crates/cairo-lang-lowering/src/utils.rs b/crates/cairo-lang-lowering/src/utils.rs index 9e3e077b606..e5455ffa662 100644 --- a/crates/cairo-lang-lowering/src/utils.rs +++ b/crates/cairo-lang-lowering/src/utils.rs @@ -4,8 +4,8 @@ use crate::ids::LocationId; use crate::{ Block, BlockEnd, BlockId, MatchArm, MatchEnumInfo, MatchEnumValue, MatchExternInfo, MatchInfo, Statement, StatementCall, StatementConst, StatementDesnap, StatementEnumConstruct, - StatementSnapshot, StatementStructConstruct, StatementStructDestructure, VarRemapping, - VarUsage, VariableId, + StatementIntoBox, StatementSnapshot, StatementStructConstruct, StatementStructDestructure, + VarRemapping, VarUsage, VariableId, }; /// Options for the `inlining-strategy` arguments. @@ -88,6 +88,10 @@ pub trait RebuilderEx<'db>: Rebuilder<'db> { input: self.map_var_usage(stmt.input), output: self.map_var_id(stmt.output), }), + Statement::IntoBox(stmt) => Statement::IntoBox(StatementIntoBox { + input: self.map_var_usage(stmt.input), + output: self.map_var_id(stmt.output), + }), }; self.transform_statement(&mut statement); statement diff --git a/crates/cairo-lang-semantic/src/corelib.rs b/crates/cairo-lang-semantic/src/corelib.rs index c1a43da40a7..76b6e82ac83 100644 --- a/crates/cairo-lang-semantic/src/corelib.rs +++ b/crates/cairo-lang-semantic/src/corelib.rs @@ -1,8 +1,8 @@ use std::sync::Arc; use cairo_lang_defs::ids::{ - EnumId, GenericTypeId, ImplDefId, ModuleId, ModuleItemId, NamedLanguageElementId, - TraitFunctionId, TraitId, + EnumId, ExternFunctionId, GenericTypeId, ImplDefId, ModuleId, ModuleItemId, + NamedLanguageElementId, TraitFunctionId, TraitId, }; use cairo_lang_diagnostics::{Maybe, ToOption}; use cairo_lang_filesystem::ids::{CrateId, SmolStrId}; @@ -998,6 +998,7 @@ pub struct CoreInfo<'db> { pub box_new_fn: TraitFunctionId<'db>, pub upcast_fn: GenericFunctionId<'db>, pub downcast_fn: GenericFunctionId<'db>, + pub into_box: ExternFunctionId<'db>, pub tuple_submodule: ModuleId<'db>, pub fixed_size_array_submodule: ModuleId<'db>, pub keyword_docs_submodule: ModuleId<'db>, @@ -1143,6 +1144,7 @@ impl<'db> CoreInfo<'db> { box_new_fn: trait_fn(box_trt, "new"), upcast_fn: bounded_int.generic_function_id("upcast"), downcast_fn: bounded_int.generic_function_id("downcast"), + into_box: box_module.extern_function_id("into_box"), tuple_submodule, fixed_size_array_submodule, keyword_docs_submodule: core.submodule("keyword_docs").id, diff --git a/crates/cairo-lang-sierra-generator/src/block_generator.rs b/crates/cairo-lang-sierra-generator/src/block_generator.rs index a81b2da7afa..0700d3afed7 100644 --- a/crates/cairo-lang-sierra-generator/src/block_generator.rs +++ b/crates/cairo-lang-sierra-generator/src/block_generator.rs @@ -23,9 +23,9 @@ use crate::utils::{ branch_align_libfunc_id, const_libfunc_id_by_type, disable_ap_tracking_libfunc_id, drop_libfunc_id, dup_libfunc_id, enable_ap_tracking_libfunc_id, enum_from_bounded_int_libfunc_id, enum_init_libfunc_id, get_concrete_libfunc_id, - get_libfunc_signature, jump_libfunc_id, jump_statement, match_enum_libfunc_id, - rename_libfunc_id, return_statement, simple_basic_statement, snapshot_take_libfunc_id, - struct_construct_libfunc_id, struct_deconstruct_libfunc_id, + get_libfunc_signature, into_box_libfunc_id, jump_libfunc_id, jump_statement, + match_enum_libfunc_id, rename_libfunc_id, return_statement, simple_basic_statement, + snapshot_take_libfunc_id, struct_construct_libfunc_id, struct_deconstruct_libfunc_id, }; /// Generates Sierra code for the body of the given [lowering::Block]. @@ -298,6 +298,9 @@ pub fn generate_statement_code<'db>( lowering::Statement::Desnap(statement) => { generate_statement_desnap(context, statement, statement_location) } + lowering::Statement::IntoBox(statement) => { + generate_statement_into_box(context, statement, statement_location) + } } } @@ -550,6 +553,25 @@ fn generate_statement_struct_construct_code<'db>( Ok(()) } +/// Generates Sierra code for [lowering::StatementIntoBox]. +fn generate_statement_into_box<'db>( + context: &mut ExprGeneratorContext<'db, '_>, + statement: &lowering::StatementIntoBox<'db>, + statement_location: &StatementLocation, +) -> Maybe<()> { + let input = maybe_add_dup_statement(context, statement_location, 0, &statement.input)?; + let stmt = simple_basic_statement( + into_box_libfunc_id( + context.get_db(), + context.get_variable_sierra_type(statement.input.var_id)?, + ), + &[input], + &[context.get_sierra_variable(statement.output)], + ); + context.push_statement(stmt); + Ok(()) +} + /// Generates Sierra code for [lowering::StatementStructDestructure]. fn generate_statement_struct_destructure_code<'db>( context: &mut ExprGeneratorContext<'db, '_>, diff --git a/crates/cairo-lang-sierra-generator/src/function_generator_test_data/struct b/crates/cairo-lang-sierra-generator/src/function_generator_test_data/struct index 5f0c512aed6..596af922d8f 100644 --- a/crates/cairo-lang-sierra-generator/src/function_generator_test_data/struct +++ b/crates/cairo-lang-sierra-generator/src/function_generator_test_data/struct @@ -52,12 +52,11 @@ foo //! > sierra_code label_test::foo::0: -dup>([0]) -> ([0], [1]) -unbox([1]) -> ([2]) -drop([2]) -> () -struct_boxed_deconstruct([0]) -> ([3], [4]) -drop>([3]) -> () -store_temp>([4]) -> ([4]) +unbox([0]) -> ([1]) +struct_deconstruct([1]) -> ([2], [3]) +drop([2]) -> () +store_temp([3]) -> ([3]) +into_box([3]) -> ([4]) return([4]) //! > ========================================================================== @@ -84,12 +83,11 @@ foo //! > sierra_code label_test::foo::0: rename>([0]) -> ([1]) -dup>([1]) -> ([1], [2]) -unbox([2]) -> ([3]) -drop([3]) -> () -struct_boxed_deconstruct([1]) -> ([4], [5]) -drop>([4]) -> () -store_temp>([5]) -> ([5]) +unbox([1]) -> ([2]) +struct_deconstruct([2]) -> ([3], [4]) +drop([3]) -> () +store_temp([4]) -> ([4]) +into_box([4]) -> ([5]) return([5]) //! > ========================================================================== @@ -120,13 +118,12 @@ struct A { //! > sierra_code label_test::foo::0: -dup>>([0]) -> ([0], [1]) -unbox>([1]) -> ([2]) -drop>([2]) -> () -struct_boxed_deconstruct>([0]) -> ([3], [4]) -drop>>>([4]) -> () -store_temp>>>([3]) -> ([3]) -return([3]) +unbox>([0]) -> ([1]) +store_temp>([1]) -> ([1]) +struct_snapshot_deconstruct([1]) -> ([2], [3]) +drop>>([3]) -> () +into_box>>([2]) -> ([4]) +return([4]) //! > ========================================================================== @@ -156,13 +153,12 @@ struct A { //! > sierra_code label_test::foo::0: -dup>>([0]) -> ([0], [1]) -unbox>([1]) -> ([2]) -drop>([2]) -> () -struct_boxed_deconstruct>([0]) -> ([3], [4]) -drop>>>([4]) -> () -store_temp>>>([3]) -> ([3]) -return([3]) +unbox>([0]) -> ([1]) +store_temp>([1]) -> ([1]) +struct_snapshot_deconstruct([1]) -> ([2], [3]) +drop>>([3]) -> () +into_box>>([2]) -> ([4]) +return([4]) //! > ========================================================================== @@ -192,10 +188,9 @@ struct A { //! > sierra_code label_test::foo::0: -dup>>([0]) -> ([0], [1]) -unbox>([1]) -> ([2]) -drop>([2]) -> () -struct_boxed_deconstruct>([0]) -> ([3], [4]) -drop>>>([4]) -> () -store_temp>>>([3]) -> ([3]) -return([3]) +unbox>([0]) -> ([1]) +store_temp>([1]) -> ([1]) +struct_snapshot_deconstruct([1]) -> ([2], [3]) +drop>>([3]) -> () +into_box>>([2]) -> ([4]) +return([4]) diff --git a/crates/cairo-lang-sierra-generator/src/local_variables.rs b/crates/cairo-lang-sierra-generator/src/local_variables.rs index a115e100eb7..aaf9fc62a94 100644 --- a/crates/cairo-lang-sierra-generator/src/local_variables.rs +++ b/crates/cairo-lang-sierra-generator/src/local_variables.rs @@ -395,6 +395,7 @@ impl<'db, 'a> FindLocalsContext<'db, 'a> { self.aliases.insert(statement_desnap.output, statement_desnap.input.var_id); BranchInfo { known_ap_change: true } } + lowering::Statement::IntoBox(_) => BranchInfo { known_ap_change: true }, }; Ok(branch_info) } diff --git a/crates/cairo-lang-sierra-generator/src/utils.rs b/crates/cairo-lang-sierra-generator/src/utils.rs index 0690bafa25a..79e9b72f9d8 100644 --- a/crates/cairo-lang-sierra-generator/src/utils.rs +++ b/crates/cairo-lang-sierra-generator/src/utils.rs @@ -122,6 +122,14 @@ pub fn struct_deconstruct_libfunc_id( }) } +/// Returns the [ConcreteLibfuncId] associated with `into_box`. +pub fn into_box_libfunc_id( + db: &dyn Database, + ty: cairo_lang_sierra::ids::ConcreteTypeId, +) -> cairo_lang_sierra::ids::ConcreteLibfuncId { + get_libfunc_id_with_generic_arg(db, "into_box", ty) +} + pub fn enum_init_libfunc_id( db: &dyn Database, ty: cairo_lang_sierra::ids::ConcreteTypeId,