leo_passes/function_inlining/mod.rs
1// Copyright (C) 2019-2025 Provable Inc.
2// This file is part of the Leo library.
3
4// The Leo library is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// The Leo library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
16
17//! The Function Inlining pass traverses the AST and inlines function at their call site.
18//! See https://en.wikipedia.org/wiki/Inline_expansion for more information.
19//! The pass also reorders `Function`s in a reconstructed `ProgramScope` so that they are in a post-order of the call graph.
20//! In other words, a callee function will appear before a caller function in the order.
21//!
22//! Consider the following flattened Leo code.
23//! ```leo
24//! function main(flag: u8, value: u8) -> u8 {
25//! $var$0 = flag == 0u8;
26//! $var$1 = foo(value);
27//! value$2 = $var$1;
28//! value$3 = $var$0 ? value$2 : value;
29//! return value$3;
30//! }
31//!
32//! inline foo(x: u8) -> u8 {
33//! $var$4 = x * x;
34//! return $var$4;
35//! }
36//! ```
37//!
38//! The inlining pass produces the following code.
39//! ```leo
40//! inline foo(x: u8) -> u8 {
41//! $var$4 = x * x;
42//! return $var$4;
43//! }
44//!
45//! function main(flag: u8, value: u8) -> u8 {
46//! $var$0 = flag == 0u8;
47//! $var$4$5 = value * value;
48//! $var$1 = $var$4$5;
49//! value$2 = $var$1;
50//! value$3 = $var$0 ? value$2 : value;
51//! return value$3;
52//! }
53//! ```
54
55use crate::Pass;
56
57use leo_ast::ProgramReconstructor as _;
58use leo_errors::Result;
59use leo_span::Symbol;
60
61mod expression;
62
63mod program;
64
65mod statement;
66
67mod visitor;
68use visitor::*;
69
70pub struct FunctionInlining;
71
72impl Pass for FunctionInlining {
73 type Input = ();
74 type Output = ();
75
76 const NAME: &str = "FunctionInlining";
77
78 fn do_pass(_input: Self::Input, state: &mut crate::CompilerState) -> Result<Self::Output> {
79 let mut ast = std::mem::take(&mut state.ast);
80 let mut visitor = FunctionInliningVisitor {
81 state,
82 reconstructed_functions: Vec::new(),
83 program: Symbol::intern(""),
84 is_async: false,
85 };
86 ast.ast = visitor.reconstruct_program(ast.ast);
87 visitor.state.handler.last_err().map_err(|e| *e)?;
88 visitor.state.ast = ast;
89 Ok(())
90 }
91}