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