Compilation Bug: itertools: .zip_eq() reached end of one iterator before the other
Th0rgal opened this issue · 2 comments
Hello,
Summary:
I found a cairo code which appears to be valid but causes a compiler crash.
Env:
scarb 2.6.4 (c4c7c0bac 2024-03-19)
cairo: 2.6.3 (https://crates.io/crates/cairo-lang-compiler/2.6.3)
sierra: 1.5.0
Context:
I am building a short but quite logic intense Starknet contract allowing abstract interactions between calls. Instead of just being able to chain calls like in a normal multicall, you can take the output a previous call and use it as the output of a future call. I added some conditional executions feature (like skipping a call given the result of a previous call) and I am now trying to add a kind of "trycatch" feature (if call A fails, perform B, otherwise perform C, then perform D).
My code looks like this:
Check whole code here: https://github.com/starknet-id/composable_multicall/blob/62bf15f3bf48a7cc8e7d82309362628baa181e9b/src/contract.cairo#L141-L150
fn execute_multicall(
mut calls: Span<DynamicCall>
) -> Array<Result<Span<felt252>, Array<felt252>>> {
let mut results: Array<Result<Span<felt252>, Array<felt252>>> = ArrayTrait::new();
let mut idx = 0;
loop {
match calls.pop_front() {
Option::Some(call) => {
match call.execution {
Execution::Static => {},
// here I skipped irrelevant executions for this bug report
Execution::Catch(call_id) => {
if results.at(*call_id).is_err() {
continue;
}
},
Execution::Then(call_id) => {
if results.at(*call_id).is_ok() {
continue;
}
},
};
let call_result = call_contract_syscall(
build_input(@results, call.to).try_into().unwrap(),
build_input(@results, call.selector),
build_inputs(@results, call.calldata.span()).span()
);
results.append(call_result);
idx = idx + 1;
},
Option::None(_) => { break; },
};
};
results
}
}
For a reason I don't understand, the specific lines:
if results.at(*call_id).is_err() {
continue;
}
And:
if results.at(*call_id).is_ok() {
continue;
}
Cause this error when compiling with scarb:
thread 'main' panicked at /Users/runner/.cargo/registry/src/index.crates.io-6f17d22bba15001f/itertools-0.11.0/src/zip_eq_impl.rs:48:13:
itertools: .zip_eq() reached end of one iterator before the other
stack backtrace:
0: 0x103bbc7c4 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::hb478ebbfb46e27ce
1: 0x103448b1c - core::fmt::write::he4d5fa2daff1f531
2: 0x103b9100c - std::io::Write::write_fmt::hc5a47a68eba63d9f
3: 0x103bbf900 - std::sys_common::backtrace::print::h79bd952cc5812e7a
4: 0x103bbf0d8 - std::panicking::default_hook::{{closure}}::h82301f6222887737
5: 0x103bc015c - std::panicking::rust_panic_with_hook::h1e70c5d905e30e9d
6: 0x1032476a4 - std::panicking::begin_panic::{{closure}}::h6387bab3c3c7976c
7: 0x103247670 - std::sys_common::backtrace::__rust_end_short_backtrace::h1c77d9eda2282a64
8: 0x103d19d88 - std::panicking::begin_panic::hfcfbfac8dda19335
9: 0x103253ff0 - cairo_lang_sierra_generator::local_variables::FindLocalsContext::analyze_branch::h131fed1660be8046
10: 0x103253c38 - cairo_lang_sierra_generator::local_variables::FindLocalsContext::analyze_call::hf071bbd16d6df1f1
11: 0x103242718 - cairo_lang_lowering::borrow_check::analysis::BackAnalysis<TAnalyzer>::get_root_info::h7162e9c7b8a27f87
12: 0x1031fff8c - cairo_lang_sierra_generator::function_generator::priv_function_with_body_sierra_data::h6dbf744a22c42758
13: 0x1031d5ad8 - salsa::derived::slot::Slot<Q,MP>::read_upgrade::h74fef216b008a522
14: 0x10322dd00 - <DB as cairo_lang_sierra_generator::db::SierraGenGroup>::priv_function_with_body_sierra_data::__shim::h3e7070a119d5a80d
15: 0x1031cc868 - salsa::derived::slot::Slot<Q,MP>::read_upgrade::h43fd41e2c3340133
16: 0x10322ef10 - <DB as cairo_lang_sierra_generator::db::SierraGenGroup>::function_with_body_sierra::__shim::hd791a39340db1b81
17: 0x1032191dc - cairo_lang_sierra_generator::program_generator::get_sierra_program_for_functions::had22e99b86b32514
18: 0x1031e1d10 - salsa::derived::slot::Slot<Q,MP>::read_upgrade::h9debe19662d40d50
19: 0x1032313c8 - <DB as cairo_lang_sierra_generator::db::SierraGenGroup>::get_sierra_program_for_functions::__shim::h025fbb67f3875f2e
20: 0x1033fdf80 - cairo_lang_test_plugin::compile_test_prepared_db::h0b0dd204866b6857
21: 0x103af6024 - <scarb::compiler::compilers::test::TestCompiler as scarb::compiler::Compiler>::compile::h21dc7d741a870ac2
22: 0x103954994 - scarb::ops::compile::compile::h1d74fe7748323707
23: 0x103b5d9fc - scarb::commands::run::hdaeb29cb348b9ce6
24: 0x103b23480 - scarb::main::hdb0c7b53413747fb
25: 0x103b667d0 - std::sys_common::backtrace::__rust_begin_short_backtrace::h06db732967bca231
26: 0x103b1fd5c - _main
Error: `scarb metadata` exited with error
Stack backtrace:
0: std::backtrace::Backtrace::capture
1: anyhow::error::<impl core::convert::From<E> for anyhow::Error>::from
2: scarb_cairo_test::main
3: std::sys_common::backtrace::__rust_begin_short_backtrace
4: _main
To reproduce:
Clone https://github.com/starknet-id/composable_multicall/
Checkout commit 62bf15f3bf48a7cc8e7d82309362628baa181e9b
(it's feat: add catch & then feature
on branch feat/try_catch
)
Note:
It appears that reordering the clauses in the match (moving Catch
& Then
on top of Except
) fixes the bug.
moved to starkware-libs/cairo#5438