use std::slice;
use cairo_lang_semantic as semantic;
use itertools::Itertools;
use super::LoweredExpr;
use super::context::LoweringContext;
use crate::ids::LocationId;
use crate::{VarUsage, VariableId};
pub fn extern_facade_return_tys<'ret, 'db: 'ret>(
db: &'db dyn salsa::Database,
ret_ty: &'ret semantic::TypeId<'db>,
) -> &'ret [semantic::TypeId<'db>] {
if let semantic::TypeLongId::Tuple(tys) = ret_ty.long(db) {
tys
} else {
slice::from_ref(ret_ty)
}
}
pub fn extern_facade_expr<'db>(
ctx: &mut LoweringContext<'db, '_>,
ty: semantic::TypeId<'db>,
returns: impl ExactSizeIterator<Item = VariableId>,
location: LocationId<'db>,
) -> LoweredExpr<'db> {
if let semantic::TypeLongId::Tuple(subtypes) = ty.long(ctx.db) {
assert_eq!(returns.len(), subtypes.len());
LoweredExpr::Tuple {
exprs: returns
.map(|var_id| LoweredExpr::AtVariable(VarUsage { var_id, location }))
.collect(),
location,
}
} else {
let Ok(var_id) = returns.exactly_one() else {
panic!("Expected exactly one output variable for non-tuple return type");
};
LoweredExpr::AtVariable(VarUsage { var_id, location })
}
}