leo_passes/type_checking/
mod.rs1mod expression;
18
19mod program;
20
21mod scope_state;
22
23mod statement;
24
25mod type_;
26
27mod visitor;
28use visitor::*;
29
30use self::scope_state::ScopeState;
31use crate::{CallGraph, CompilerState, Pass, StructGraph};
32
33use leo_ast::ProgramVisitor;
34use leo_errors::Result;
35
36use indexmap::{IndexMap, IndexSet};
37
38#[derive(Clone)]
40pub struct TypeCheckingInput {
41 pub max_array_elements: usize,
42 pub max_mappings: usize,
43 pub max_functions: usize,
44}
45
46pub struct TypeChecking;
50
51impl Pass for TypeChecking {
52 type Input = TypeCheckingInput;
53 type Output = ();
54
55 const NAME: &'static str = "TypeChecking";
56
57 fn do_pass(input: Self::Input, state: &mut CompilerState) -> Result<Self::Output> {
58 let struct_names = state
59 .symbol_table
60 .iter_records()
61 .map(|(loc, _)| loc.name)
62 .chain(state.symbol_table.iter_structs().map(|(name, _)| name))
63 .collect();
64 let function_names = state.symbol_table.iter_functions().map(|(loc, _)| loc.name).collect();
65
66 let ast = std::mem::take(&mut state.ast);
67
68 state.struct_graph = StructGraph::new(struct_names);
70 state.call_graph = CallGraph::new(function_names);
71
72 let mut visitor = TypeCheckingVisitor {
73 state,
74 scope_state: ScopeState::new(),
75 async_function_input_types: IndexMap::new(),
76 async_function_callers: IndexMap::new(),
77 used_structs: IndexSet::new(),
78 conditional_scopes: Vec::new(),
79 limits: input,
80 };
81 visitor.visit_program(ast.as_repr());
82 visitor.state.handler.last_err().map_err(|e| *e)?;
83
84 visitor.state.struct_graph.retain_nodes(&visitor.used_structs);
87 visitor.state.ast = ast;
88
89 Ok(())
90 }
91}