Skip to content

Commit c83c966

Browse files
Fix issue #3863
1 parent a3c3ada commit c83c966

File tree

3 files changed

+59
-3
lines changed

3 files changed

+59
-3
lines changed

crates/cairo-lang-sierra-generator/src/store_variables/mod.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,8 @@ impl<'a> AddStoreVariableStatements<'a> {
249249
res_deferred_info = Some(deferred_info);
250250
}
251251

252-
if self.state().temporary_variables.get(arg).is_some() {
253-
self.store_temp_as_local(arg);
252+
if self.state().temporary_variables.get(arg).is_some() && self.store_temp_as_local(arg) {
253+
self.known_stack().remove_variable(arg);
254254
}
255255

256256
(false, res_deferred_info)
@@ -365,11 +365,13 @@ impl<'a> AddStoreVariableStatements<'a> {
365365

366366
/// Copies the given variable into a local variable if it is marked as local.
367367
/// Removes it from [State::temporary_variables].
368-
fn store_temp_as_local(&mut self, var: &sierra::ids::VarId) {
368+
fn store_temp_as_local(&mut self, var: &sierra::ids::VarId) -> bool {
369369
if let Some(uninitialized_local_var_id) = self.local_variables.get(var).cloned() {
370370
let ty = self.state().temporary_variables.swap_remove(var).unwrap();
371371
self.store_local(var, &uninitialized_local_var_id, &ty);
372+
return true;
372373
}
374+
false
373375
}
374376

375377
/// Stores all the deffered and temporary variables as local variables.

tests/bug_samples/issue3863.cairo

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
use array::{ArrayTrait, SpanTrait};
2+
use option::OptionTrait;
3+
/// The call context.
4+
#[derive(Destruct)]
5+
struct CallContext {
6+
/// The bytecode to execute.
7+
bytecode: Span<u8>,
8+
/// The call data.
9+
call_data: Span<u8>,
10+
/// Amount of native token to transfer.
11+
value: u256,
12+
}
13+
14+
15+
trait CallContextTrait {
16+
fn new(bytecode: Span<u8>, call_data: Span<u8>, value: u256) -> CallContext;
17+
fn bytecode(self: @CallContext) -> Span<u8>;
18+
fn call_data(self: @CallContext) -> Span<u8>;
19+
fn value(self: @CallContext) -> u256;
20+
}
21+
22+
impl CallContextImpl of CallContextTrait {
23+
fn new(bytecode: Span<u8>, call_data: Span<u8>, value: u256) -> CallContext {
24+
CallContext { bytecode, call_data, value, }
25+
}
26+
fn bytecode(self: @CallContext) -> Span<u8> {
27+
*self.bytecode
28+
}
29+
30+
fn call_data(self: @CallContext) -> Span<u8> {
31+
*self.call_data
32+
}
33+
34+
fn value(self: @CallContext) -> u256 {
35+
*self.value
36+
}
37+
}
38+
39+
#[test]
40+
#[available_gas(1000000)]
41+
fn test_call_context_new() {
42+
// Given
43+
let bytecode = array![1, 2, 3];
44+
let call_data = array![4, 5, 6];
45+
let value: u256 = 100;
46+
// When
47+
let call_context = CallContextTrait::new(bytecode.span(), call_data.span(), value);
48+
// Then
49+
assert(call_context.bytecode() == bytecode.span(), 'wrong bytecode');
50+
assert(call_context.call_data() == call_data.span(), 'wrong call data');
51+
assert(call_context.value() == value, 'wrong value');
52+
}

tests/bug_samples/lib.cairo

+2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@ mod issue3192;
2323
mod issue3211;
2424
mod issue3345;
2525
mod issue3658;
26+
mod issue3863;
2627
mod loop_only_change;
2728
mod inconsistent_gas;
2829
mod partial_param_local;
2930
mod loop_break_in_match;
3031
mod generic_cycles;
32+

0 commit comments

Comments
 (0)