Skip to main content

cairo_lang_lowering/lower/
external.rs

1use std::slice;
2
3use cairo_lang_semantic as semantic;
4use itertools::Itertools;
5
6use super::LoweredExpr;
7use super::context::LoweringContext;
8use crate::ids::LocationId;
9use crate::{VarUsage, VariableId};
10
11/// Given a return type of an external function, gets the real output variable types for that call.
12/// For example, an external function that returns a tuple, has an output variable for each tuple
13/// entry.
14pub fn extern_facade_return_tys<'ret, 'db: 'ret>(
15    db: &'db dyn salsa::Database,
16    ret_ty: &'ret semantic::TypeId<'db>,
17) -> &'ret [semantic::TypeId<'db>] {
18    if let semantic::TypeLongId::Tuple(tys) = ret_ty.long(db) {
19        tys
20    } else {
21        slice::from_ref(ret_ty)
22    }
23}
24
25/// Given the returned output variables from an external function call, creates a LoweredExpr
26/// representing the return expression of the type that was declared in the signature.
27/// For example, for an external function that returns a tuple, even though it will have an output
28/// variable for each entry, the return expression is a single value of type tuple.
29pub fn extern_facade_expr<'db>(
30    ctx: &mut LoweringContext<'db, '_>,
31    ty: semantic::TypeId<'db>,
32    returns: impl ExactSizeIterator<Item = VariableId>,
33    location: LocationId<'db>,
34) -> LoweredExpr<'db> {
35    if let semantic::TypeLongId::Tuple(subtypes) = ty.long(ctx.db) {
36        assert_eq!(returns.len(), subtypes.len());
37        // TODO(ilya): Use tuple item location for each item.
38        LoweredExpr::Tuple {
39            exprs: returns
40                .map(|var_id| LoweredExpr::AtVariable(VarUsage { var_id, location }))
41                .collect(),
42            location,
43        }
44    } else {
45        let Ok(var_id) = returns.exactly_one() else {
46            panic!("Expected exactly one output variable for non-tuple return type");
47        };
48        LoweredExpr::AtVariable(VarUsage { var_id, location })
49    }
50}