cairo_lang_lowering/lower/
external.rs

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