Repository: starkware-libs/cairo (language: rust)

Issue:
bug: Variant extract failed
# Bug Report

**Cairo version:**
scarb 2.9.2+nightly-2025-02-01 (3a752f93d 2025-02-01)
cairo: 2.9.2 (99f052811)
sierra: 1.6.0

This code fails:

```
#[derive(Copy, Drop, Debug)]
enum Food {
    CordonBleu,
    Steak,
    Sushi,
}

#[derive(Copy, Drop, Debug)]
enum Day {
    Monday,
    Tuesday,
    Wednesday,
}

// We don't have the ingredients to make Sushi.
fn have_ingredients(food: Food) -> Option<Food> {
    match food {
        Food::Sushi => Option::None,
        _ => Option::Some(food),
    }
}

// We have the recipe for everything except Cordon Bleu.
fn have_recipe(food: Food) -> Option<Food> {
    match food {
        Food::CordonBleu => Option::None,
        _ => Option::Some(food),
    }
}

// This can conveniently be rewritten more compactly with `and_then()`:
fn cookable_v3(food: Food) -> Option<Food> {
    have_recipe(food).and_then(|| have_ingredients(food))
}


fn eat(food: Food, day: Day) {
    match cookable_v3(food) {
        Option::Some(food) => println!("Yay! On {:?} we get to eat {:?}.", day, food),
        Option::None => println!("Oh no. We don't get to eat on {:?}?", day),
    }
}

fn main() {
    let cordon_bleu= Food::CordonBleu;
    eat(cordon_bleu, Day::Monday);
}
```

The issue is in `cookable_v3` where we capture `food` from the closure's environment instead of using the `some_food` returned from `and_then`. But it should be valid

```
thread 'scarb compile and_then-eubo84o80rjps' panicked at /Users/runner/.cargo/git/checkouts/cairo-f086c7e6d4098a68/99f0528/crates/cairo-lang-sierra-generator/src/utils.rs:399:21:
Variant extract failed: `Impl(ImplGenericFunctionId { impl_id: ImplId(5), function: TraitFunctionId(53) })` is not of variant `GenericFunctionId::Extern`
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread 'main' panicked at scarb/src/ops/compile.rs:197:14:
Compiler thread has panicked.: Any { .. }
```


Discussion / hints:
May I try my hand at this?
the error seems to be about validation of closure params count - replacing:
```
have_recipe(food).and_then(|| have_ingredients(food))
```
with 
```
have_recipe(food).and_then(|_x| have_ingredients(food))
```
works.
will obviously fix the diagnostic.

Fix patch:
diff --git a/crates/cairo-lang-semantic/src/expr/compute.rs b/crates/cairo-lang-semantic/src/expr/compute.rs
index cf508470c9f..35bb6dda1c6 100644
--- a/crates/cairo-lang-semantic/src/expr/compute.rs
+++ b/crates/cairo-lang-semantic/src/expr/compute.rs
@@ -1694,7 +1694,11 @@ fn compute_expr_closure_semantic(
         if let Some(param_types) = params_tuple_ty {
             if let Err(err_set) = new_ctx.resolver.inference().conform_ty(closure_type, param_types)
             {
-                new_ctx.resolver.inference().consume_error_without_reporting(err_set);
+                new_ctx.resolver.inference().report_on_pending_error(
+                    err_set,
+                    new_ctx.diagnostics,
+                    syntax.stable_ptr().untyped(),
+                );
             }
         }
 


Test patch:
diff --git a/crates/cairo-lang-semantic/src/expr/test_data/closure b/crates/cairo-lang-semantic/src/expr/test_data/closure
index a18a4e8c37b..fee183ad667 100644
--- a/crates/cairo-lang-semantic/src/expr/test_data/closure
+++ b/crates/cairo-lang-semantic/src/expr/test_data/closure
@@ -819,3 +819,29 @@ error: Ambiguous method call. More than one applicable trait function with a sui
  --> lib.cairo:9:13
         arr.len();
             ^^^
+
+//! > ==========================================================================
+
+//! > Closures bad param count.
+
+//! > test_runner_name
+test_function_diagnostics(expect_diagnostics: true)
+
+//! > function
+fn foo() {
+    call_with(|| {})
+}
+
+//! > function_name
+foo
+
+//! > module_code
+fn call_with<F, +core::ops::Fn<F, (i32,)>>(func: F) {
+    func(1);
+}
+
+//! > expected_diagnostics
+error: Type mismatch: `()` and `(core::integer::i32,)`.
+ --> lib.cairo:5:15
+    call_with(|| {})
+              ^^^^^