cairo-lang-lowering 2.4.1

Cairo lowering phase.
Documentation
//! > Test empty function.

//! > test_runner_name
test_function_lowering

//! > function
fn foo() {
}

//! > function_name
foo

//! > module_code

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_flat
Parameters:
blk0 (root):
Statements:
  (v0: ()) <- struct_construct()
End:
  Return(v0)

//! > ==========================================================================

//! > Test unreachable code.

//! > test_runner_name
test_function_lowering

//! > function
fn foo(a: felt252) -> felt252 {
    return a + a * a;
    5;6;7
}

//! > function_name
foo

//! > module_code

//! > semantic_diagnostics

//! > lowering_diagnostics
error: Unreachable code
 --> lib.cairo:3:5
    5;6;7
    ^**^

//! > lowering_flat
Parameters: v0: core::felt252
blk0 (root):
Statements:
  (v3: core::felt252) <- core::felt252_mul(v0, v0)
  (v4: core::felt252) <- core::felt252_add(v0, v3)
End:
  Return(v4)

//! > ==========================================================================

//! > Test unreachable code by match.

//! > test_runner_name
test_function_lowering

//! > function
fn foo(a: never) -> felt252 {
    match a {};
    1+2
}

//! > function_name
foo

//! > module_code

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_flat
Parameters: v0: core::never
blk0 (root):
Statements:
End:
  Match(match_enum(v0) {
  })

//! > ==========================================================================

//! > Test single patterns.

//! > test_runner_name
test_function_lowering

//! > function
fn foo(a: felt252) -> felt252 {
    let (_, b) = (1, a);
    5
}

//! > function_name
foo

//! > module_code

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_flat
Parameters: v0: core::felt252
blk0 (root):
Statements:
  (v2: core::felt252) <- 5u
End:
  Return(v2)

//! > ==========================================================================

//! > Test compound expressions.

//! > test_runner_name
test_function_lowering

//! > function
fn foo(a: felt252) -> felt252 {
  let x = {7;};
  {x;}
  let y = if 1 == 1 { 6 } else { 7 };
  foo(3) + 5 * {3; a + 0}
}

//! > function_name
foo

//! > module_code

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_flat
Parameters: v36: core::RangeCheck, v37: core::gas::GasBuiltin, v0: core::felt252
blk0 (root):
Statements:
  (v27: core::gas::BuiltinCosts) <- core::gas::get_builtin_costs()
End:
  Match(match core::gas::withdraw_gas_all(v36, v37, v27) {
    Option::Some(v38, v39) => blk1,
    Option::None(v40, v41) => blk7,
  })

blk1:
Statements:
  (v3: core::felt252) <- 1u
  (v4: core::felt252) <- 1u
  (v18: core::felt252) <- core::felt252_sub(v3, v4)
End:
  Match(match core::felt252_is_zero(v18) {
    IsZeroResult::Zero => blk2,
    IsZeroResult::NonZero(v7) => blk3,
  })

blk2:
Statements:
End:
  Goto(blk4, {})

blk3:
Statements:
End:
  Goto(blk4, {})

blk4:
Statements:
  (v10: core::felt252) <- 3u
  (v48: core::RangeCheck, v49: core::gas::GasBuiltin, v28: core::panics::PanicResult::<(core::felt252,)>) <- test::foo(v38, v39, v10)
End:
  Match(match_enum(v28) {
    PanicResult::Ok(v29) => blk5,
    PanicResult::Err(v31) => blk6,
  })

blk5:
Statements:
  (v14: core::felt252) <- 0u
  (v19: core::felt252) <- core::felt252_add(v0, v14)
  (v12: core::felt252) <- 5u
  (v20: core::felt252) <- core::felt252_mul(v12, v19)
  (v30: core::felt252) <- struct_destructure(v29)
  (v21: core::felt252) <- core::felt252_add(v30, v20)
  (v32: (core::felt252,)) <- struct_construct(v21)
  (v33: core::panics::PanicResult::<(core::felt252,)>) <- PanicResult::Ok(v32)
End:
  Return(v48, v49, v33)

blk6:
Statements:
  (v35: core::panics::PanicResult::<(core::felt252,)>) <- PanicResult::Err(v31)
End:
  Return(v48, v49, v35)

blk7:
Statements:
  (v22: core::array::Array::<core::felt252>) <- core::array::array_new::<core::felt252>()
  (v23: core::felt252) <- 375233589013918064796019u
  (v25: core::array::Array::<core::felt252>) <- core::array::array_append::<core::felt252>(v22, v23)
  (v24: core::panics::Panic) <- struct_construct()
  (v26: (core::panics::Panic, core::array::Array::<core::felt252>)) <- struct_construct(v24, v25)
  (v34: core::panics::PanicResult::<(core::felt252,)>) <- PanicResult::Err(v26)
End:
  Return(v40, v41, v34)

//! > ==========================================================================

//! > Test match enum.

//! > test_runner_name
test_function_lowering

//! > function
fn foo(x: MyEnum) -> felt252 {
  match x {
    MyEnum::A(inner) => {return 5;},
    MyEnum::B(inner) => {inner},
    MyEnum::C(inner) => {
      // A workaround to drop inner.
      let (a, b) = inner.unbox();
      7
    }
  }
}

//! > function_name
foo

//! > module_code
enum MyEnum {
  A: (),
  B: felt252,
  C: Box::<((), felt252)>,
}

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_flat
Parameters: v0: test::MyEnum
blk0 (root):
Statements:
End:
  Match(match_enum(v0) {
    MyEnum::A(v1) => blk1,
    MyEnum::B(v3) => blk2,
    MyEnum::C(v4) => blk3,
  })

blk1:
Statements:
  (v2: core::felt252) <- 5u
End:
  Return(v2)

blk2:
Statements:
End:
  Goto(blk4, {v3 -> v9})

blk3:
Statements:
  (v10: ((), core::felt252)) <- core::box::unbox::<((), core::felt252)>(v4)
  (v8: core::felt252) <- 7u
End:
  Goto(blk4, {v8 -> v9})

blk4:
Statements:
End:
  Return(v9)

//! > ==========================================================================

//! > Test literal generic argument.

//! > test_runner_name
test_function_lowering

//! > function
fn foo(a : Array::<felt252, 5>) -> felt252 {
  felt252_const::<17>()
}

//! > function_name
foo

//! > module_code
type Array<T,const N: usize> = (T,felt252);

//! > semantic_diagnostics
error: Const generic args are not allowed in this context.
 --> lib.cairo:1:14
type Array<T,const N: usize> = (T,felt252);
             ^************^

//! > lowering_diagnostics

//! > lowering_flat
Parameters: v0: (core::felt252, core::felt252)
blk0 (root):
Statements:
  (v1: core::felt252) <- core::felt252_const::<LiteralLongId { value: 17 }>()
End:
  Return(v1)

//! > ==========================================================================

//! > Test passing same argument as two ref params.

//! > Comments
TODO(spapini): Make this a semantic diagnostic.

//! > test_runner_name
test_function_lowering

//! > function
fn foo(mut a : felt252) -> felt252 {
  bar(ref a, ref a)
}

//! > function_name
foo

//! > module_code
fn bar(ref a: felt252, ref b: felt252) -> felt252  {
  a = 0;
  b = 1;
  a + b
}

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_flat
Parameters: v0: core::felt252
blk0 (root):
Statements:
  (v2: core::felt252, v3: core::felt252, v1: core::felt252) <- test::bar(v0, v0)
End:
  Return(v1)

//! > ==========================================================================

//! > Test concretization with bad types.

//! > test_runner_name
test_function_lowering

//! > function
fn foo(mut data: Span::<felt252>) -> u128 {
   serde::Serde::<u128>::deserialize(ref data)
}

//! > function_name
foo

//! > module_code

//! > semantic_diagnostics
error: Unexpected return type. Expected: "core::integer::u128", found: "core::option::Option::<core::integer::u128>".
 --> lib.cairo:1:43
fn foo(mut data: Span::<felt252>) -> u128 {
                                          ^

//! > lowering_diagnostics

//! > lowering_flat