@@ -183,6 +183,18 @@ pub fn build_enum_value<'ctx, 'this>(
183183}
184184
185185/// Generate MLIR operations for the `enum_from_bounded_int` libfunc.
186+ ///
187+ /// # Constraints
188+ ///
189+ /// - The target `Enum` must contain the same number of empty variants as the number
190+ /// of possible values in the `BoundedInt` range.
191+ /// - The range of the `BoundedInt` must start from **0**.
192+ ///
193+ /// # Signature
194+ ///
195+ /// ```cairo
196+ /// fn enum_from_bounded_int<T, U>(index: U) -> T nopanic
197+ /// ```
186198pub fn build_from_bounded_int < ' ctx , ' this > (
187199 context : & ' ctx Context ,
188200 registry : & ProgramRegistry < CoreType , CoreLibfunc > ,
@@ -545,7 +557,7 @@ pub fn build_snapshot_match<'ctx, 'this>(
545557mod test {
546558 use crate :: {
547559 context:: NativeContext , jit_enum, jit_struct, load_cairo,
548- utils:: testing:: run_program_assert_output,
560+ utils:: testing:: run_program_assert_output, Value ,
549561 } ;
550562 use cairo_lang_sierra:: program:: Program ;
551563 use lazy_static:: lazy_static;
@@ -647,4 +659,78 @@ mod test {
647659 . compile ( & program, false , Some ( Default :: default ( ) ) , None )
648660 . unwrap ( ) ;
649661 }
662+
663+ #[ test]
664+ fn create_enum_from_bounded_int ( ) {
665+ let program = load_cairo ! {
666+ #[ feature( "bounded-int-utils" ) ]
667+ use core:: internal:: bounded_int:: BoundedInt ;
668+ mod b0x4 {
669+ #[ feature( "bounded-int-utils" ) ]
670+ use core:: internal:: bounded_int:: BoundedInt ;
671+ pub extern fn enum_from_bounded_int<T >( index: BoundedInt <0 , 4 >) -> T nopanic;
672+
673+ // This wrapper is required so that the compiler won't assume extern `enum_from_bounded_int` is a
674+ // branch function. Without it, the program does not compile.
675+ fn wrapper<T >( index: BoundedInt <0 , 4 >) -> T {
676+ enum_from_bounded_int( index)
677+ }
678+ }
679+
680+ mod b0x0 {
681+ #[ feature( "bounded-int-utils" ) ]
682+ use core:: internal:: bounded_int:: BoundedInt ;
683+ pub extern fn enum_from_bounded_int<T >( index: BoundedInt <0 , 0 >) -> T nopanic;
684+
685+ // This wrapper is required so that the compiler won't assume extern `enum_from_bounded_int` is a
686+ // branch function. Without it, the program does not compile.
687+ fn wrapper<T >( index: BoundedInt <0 , 0 >) -> T {
688+ enum_from_bounded_int( index)
689+ }
690+ }
691+
692+ enum Enum1 {
693+ Zero
694+ }
695+
696+ enum Enum5 {
697+ Zero ,
698+ One ,
699+ Two ,
700+ Three ,
701+ Four
702+ }
703+
704+ fn test_1_variants( input: felt252) -> Enum1 {
705+ let bi: BoundedInt <0 , 0 > = input. try_into( ) . unwrap( ) ;
706+ b0x0:: wrapper( bi)
707+ }
708+
709+ fn test_5_variants( input: felt252) -> Enum5 {
710+ let bi: BoundedInt <0 , 4 > = input. try_into( ) . unwrap( ) ;
711+ b0x4:: wrapper( bi)
712+ }
713+ } ;
714+
715+ run_program_assert_output (
716+ & program,
717+ "test_1_variants" ,
718+ & [ Value :: Felt252 ( 0 . into ( ) ) ] ,
719+ jit_enum ! ( 0 , jit_struct!( jit_enum!( 0 , jit_struct!( ) ) ) ) ,
720+ ) ;
721+
722+ run_program_assert_output (
723+ & program,
724+ "test_5_variants" ,
725+ & [ Value :: Felt252 ( 0 . into ( ) ) ] ,
726+ jit_enum ! ( 0 , jit_struct!( jit_enum!( 0 , jit_struct!( ) ) ) ) ,
727+ ) ;
728+
729+ run_program_assert_output (
730+ & program,
731+ "test_5_variants" ,
732+ & [ Value :: Felt252 ( 4 . into ( ) ) ] ,
733+ jit_enum ! ( 0 , jit_struct!( jit_enum!( 4 , jit_struct!( ) ) ) ) ,
734+ ) ;
735+ }
650736}
0 commit comments