Skip to content

Commit 2d27b81

Browse files
fixed a bug where coupons type is not calculated correctly at return types (#1630)
1 parent 6f9b90b commit 2d27b81

6 files changed

Lines changed: 66 additions & 2 deletions

File tree

src/libfuncs/function_call.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ pub fn build<'ctx, 'this>(
248248
// Complex return type. Just extract the values from the struct, since LLVM will
249249
// handle the rest.
250250

251+
let mut count = 0;
251252
for (idx, type_id) in info.function.signature.ret_types.iter().enumerate() {
252253
let type_info = registry.get_type(type_id)?;
253254

@@ -258,9 +259,10 @@ pub fn build<'ctx, 'this>(
258259
context,
259260
location,
260261
function_call_result,
261-
result_types[idx],
262-
idx,
262+
result_types[count],
263+
count,
263264
)?;
265+
count += 1;
264266

265267
results.push(val);
266268
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[crate_roots]
2+
coupons_function_param = "."
3+
4+
[config.global]
5+
edition = "2023_01"
6+
7+
[config.global.experimental_features]
8+
negative_impls = false
9+
associated_item_constraints = false
10+
coupons = true
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
extern fn coupon_buy<T>() -> T nopanic;
2+
fn run_test(mut x: felt252) {
3+
4+
let mut y = x + 4;
5+
let mut c = coupon_buy();
6+
bar(ref x, ref c, ref y);
7+
foo(__coupon__: c);
8+
}
9+
#[inline(never)]
10+
fn foo() {
11+
12+
}
13+
#[inline(never)]
14+
fn bar(ref x: felt252, ref c: foo::Coupon, ref y: felt252) {
15+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mod coupons_function_param;

tests/tests/coupon.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use crate::common::{compare_outputs, run_native_program, run_vm_program, DEFAULT_GAS};
2+
use cairo_lang_runner::Arg;
3+
use cairo_native::starknet::DummySyscallHandler;
4+
use cairo_native::utils::testing::load_program_and_runner;
5+
use cairo_native::Value;
6+
use starknet_types_core::felt::Felt;
7+
8+
#[test]
9+
fn return_coupon() {
10+
let program = &load_program_and_runner("programs/coupons_function_param");
11+
let x = 5;
12+
13+
let result_vm = run_vm_program(
14+
program,
15+
"run_test",
16+
vec![Arg::Value(Felt::from(x))],
17+
Some(DEFAULT_GAS as usize),
18+
)
19+
.unwrap();
20+
let result_native = run_native_program(
21+
program,
22+
"run_test",
23+
&[Value::Felt252(Felt::from(x))],
24+
Some(DEFAULT_GAS),
25+
Option::<DummySyscallHandler>::None,
26+
);
27+
28+
compare_outputs(
29+
&program.1,
30+
&program.2.find_function("run_test").unwrap().id,
31+
&result_vm,
32+
&result_native,
33+
)
34+
.expect("coupon function call diverges between VM and native");
35+
}

tests/tests/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ pub mod boolean;
44
pub mod cases;
55
pub mod circuit;
66
pub mod compile_library;
7+
pub mod coupon;
78
pub mod dict;
89
pub mod e2e_libfuncs;
910
pub mod ec;

0 commit comments

Comments
 (0)