cairo_lang_lowering/concretize/
mod.rs1use cairo_lang_diagnostics::Maybe;
2use cairo_lang_semantic::substitution::GenericSubstitution;
3use cairo_lang_semantic::types::TypeInfo;
4use cairo_lang_utils::Intern;
5use salsa::Database;
6
7use crate::ids::{FunctionId, FunctionLongId, GeneratedFunction, SemanticFunctionIdEx};
8use crate::{BlockEnd, Lowered, MatchArm, Statement};
9
10fn concretize_function<'db>(
12 db: &'db dyn Database,
13 substitution: &GenericSubstitution<'db>,
14 function: FunctionId<'db>,
15) -> Maybe<FunctionId<'db>> {
16 match function.long(db) {
17 FunctionLongId::Semantic(id) => {
18 Ok(substitution.substitute(db, *id)?.lowered(db))
20 }
21 FunctionLongId::Generated(GeneratedFunction { parent, key }) => {
22 Ok(FunctionLongId::Generated(GeneratedFunction {
23 parent: substitution.substitute(db, *parent)?,
24 key: *key,
25 })
26 .intern(db))
27 }
28 FunctionLongId::Specialized(_) => {
29 unreachable!("Specialization of functions only occurs post concretization.")
30 }
31 }
32}
33
34pub fn concretize_lowered<'db>(
37 db: &'db dyn Database,
38 lowered: &mut Lowered<'db>,
39 substitution: &GenericSubstitution<'db>,
40) -> Maybe<()> {
41 for (_, var) in lowered.variables.iter_mut() {
43 var.ty = substitution.substitute(db, var.ty)?;
44 let TypeInfo { destruct_impl, panic_destruct_impl, .. } = &mut var.info;
45 for impl_id in [destruct_impl, panic_destruct_impl].into_iter().flatten() {
46 *impl_id = substitution.substitute(db, *impl_id)?;
47 }
48 }
49 for block in lowered.blocks.iter_mut() {
51 for stmt in block.statements.iter_mut() {
52 match stmt {
53 Statement::Call(stmt) => {
54 stmt.function = concretize_function(db, substitution, stmt.function)?;
55 }
56 Statement::EnumConstruct(stmt) => {
57 stmt.variant = substitution.substitute(db, stmt.variant)?;
58 }
59 Statement::Const(stmt) => {
60 stmt.value = substitution.substitute(db, stmt.value)?;
61 }
62 Statement::Snapshot(_)
63 | Statement::Desnap(_)
64 | Statement::StructConstruct(_)
65 | Statement::StructDestructure(_) => {}
66 }
67 }
68 if let BlockEnd::Match { info } = &mut block.end {
69 for MatchArm { arm_selector: selector, .. } in match info {
70 crate::MatchInfo::Enum(s) => s.arms.iter_mut(),
71 crate::MatchInfo::Extern(s) => {
72 s.function = concretize_function(db, substitution, s.function)?;
73 s.arms.iter_mut()
74 }
75 crate::MatchInfo::Value(s) => s.arms.iter_mut(),
76 } {
77 *selector = substitution.substitute(db, selector.clone())?;
78 }
79 }
80 }
81 lowered.signature = substitution.substitute(db, lowered.signature.clone())?;
82
83 Ok(())
84}