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

Issue:
bug: Error during libfunc specialization of function_call
# Bug Report

**Cairo version:**
2.9.2
<!-- Please specify commit or tag version. -->

**Current behavior:**
MRE:

```rust

#[generate_trait]
impl ResultExtImpl<T, E> of ResultExTrait<T, E> {
    /// Calls `op` if the result is `Ok`, otherwise returns the `Err` value of `self`.
    ///
    /// This function can be used for control flow based on `Result` values.
    ///
    /// # Examples
    ///
    /// ```
    /// use core::num::traits::CheckedMul;
    ///
    /// fn sq_then_string(x: u32) -> Result<ByteArray, ByteArray> {
    ///     let res = x.checked_mul(x).ok_or("overflowed");
    ///     res.and_then(|v| Result::Ok(format!("{}", v)))
    /// }
    ///
    /// let x = sq_then_string(4);
    /// assert!(x == Result::Ok("16"));
    ///
    /// let y = sq_then_string(65536);
    /// assert!(y == Result::Err("overflowed"));
    ///
    /// ```
    #[inline]
    fn and_then<U, F, +Drop<F>, impl func: core::ops::FnOnce<F, (T,)>[Output: Result<U, E>]>(
        self: Result<T, E>, op: F,
    ) -> Result<U, E> {
        match self {
            Result::Ok(t) => op(t),
            Result::Err(e) => Result::Err(e),
        }
    }
}

fn main(){
    let sq_then_string = |x: u32| -> Result<
    ByteArray, ByteArray,
> {
    let res = core::num::traits::CheckedMul::checked_mul(x, x).ok_or("overflowed");
    res.and_then(|v| Result::Ok(format!("{}", v)))
};

    let y = sq_then_string(65536);
    assert!(y == Result::Err("overflowed"));
    println!("y: {:?}", y);
}
```

Running `scarb cairo-run` on this program yields the error:

```
error: Failed calculating gas usage, it is likely a call for `gas::withdraw_gas` is missing. Inner error: error from the program registry

Caused by:
    0: error from the program registry
    1: Error during libfunc specialization of function_call<user@Generated core::ops::function::Fn::<{closure@/Users/msaug/workspace/sandbox/tmp/src/lib.cairo:188:26: 188:34}, (core::integer::u32,)>::call>: Could not specialize libfunc `function_call` with generic_args: [user@Generated core::ops::function::Fn::<{closure@/Users/msaug/workspace/sandbox/tmp/src/lib.cairo:188:26: 188:34}, (core::integer::u32,)>::call]. Error: Could not find the requested function.
 ```
<!-- Describe how the bug manifests. -->

**Expected behavior:**
Compile-time error, or successful run.
<!-- Describe what you expect the behavior to be without the bug. -->



Discussion / hints:

Fix patch:
diff --git a/crates/cairo-lang-lowering/src/ids.rs b/crates/cairo-lang-lowering/src/ids.rs
index 4e656fd3d52..e1ced62a241 100644
--- a/crates/cairo-lang-lowering/src/ids.rs
+++ b/crates/cairo-lang-lowering/src/ids.rs
@@ -359,7 +359,16 @@ pub trait SemanticFunctionIdEx {
 }
 impl SemanticFunctionIdEx for semantic::FunctionId {
     fn lowered(&self, db: &dyn LoweringGroup) -> FunctionId {
-        FunctionLongId::Semantic(*self).intern(db)
+        let ret = FunctionLongId::Semantic(*self).intern(db);
+        // If the function is generated, we need to check if it has a body, so we can return its
+        // generated function id.
+        // TODO(orizi): This is a hack, we should have a better way to do this.
+        if let Ok(Some(body)) = ret.body(db) {
+            if let Ok(id) = body.function_id(db) {
+                return id;
+            }
+        }
+        ret
     }
 }
 impl<'a> DebugWithDb<dyn LoweringGroup + 'a> for FunctionLongId {


Test patch:
diff --git a/tests/bug_samples/cairo_project.toml b/tests/bug_samples/cairo_project.toml
index eaf72a31dfd..b2ffc43638d 100644
--- a/tests/bug_samples/cairo_project.toml
+++ b/tests/bug_samples/cairo_project.toml
@@ -3,3 +3,7 @@ bug_samples = "."
 
 [config.global]
 edition = "2023_10"
+
+[config.global.experimental_features]
+negative_impls = true
+associated_item_constraints = true
diff --git a/tests/bug_samples/issue6920.cairo b/tests/bug_samples/issue6920.cairo
new file mode 100644
index 00000000000..38a5c0f21f2
--- /dev/null
+++ b/tests/bug_samples/issue6920.cairo
@@ -0,0 +1,11 @@
+#[test]
+fn uninlined_closure_test() {
+    let uninlined_closure = 
+        || {
+            let a: felt252 = 256;
+            format!(
+                "wow such amazing calcs {a} wow such amazing calcs {a} wow such amazing calcs {a}",
+            );
+        };
+    let _ = uninlined_closure();
+}
diff --git a/tests/bug_samples/lib.cairo b/tests/bug_samples/lib.cairo
index bfefab0a61b..84312857dd4 100644
--- a/tests/bug_samples/lib.cairo
+++ b/tests/bug_samples/lib.cairo
@@ -51,6 +51,7 @@ mod issue5967;
 mod issue6580;
 mod issue6623;
 mod issue6755;
+mod issue6920;
 mod loop_break_in_match;
 mod loop_only_change;
 mod partial_param_local;