leo_passes/path_resolution/
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//! A transform pass that resolves and reconstructs AST paths by prefixing them with the current module path.
18//!
19//! The main goal is to fully qualify all paths by prepending the current module's path segments
20//! before semantic analysis is performed. Since semantic information (e.g., symbol resolution)
21//! is not yet available at this stage, this pass conservatively prefixes all paths to ensure
22//! that references to items (functions, types, constants, structs) are correctly scoped.
23//!
24//! # Key behaviors:
25//! - Composite types have their `resolved_path` set to the concatenation of the current module path and the type's path.
26//! - Function call expressions have their function path fully qualified similarly.
27//! - Struct initializers have their paths prefixed, and their member expressions recursively reconstructed.
28//! - Standalone paths are prefixed as well, accounting for possible global constants.
29//!
30//! # Note:
31//! This pass does not perform full semantic resolution; it prepares the AST paths for later
32//! stages by making all paths absolute or fully qualified relative to the current module context.
33//!
34//! # Example
35//!
36//! Input (in module `foo`):
37//! ```leo
38//! struct Bar { x: u32 }
39//! const Y: u32 = 1;
40//! transition t() { let z = Bar { x: Y }; }
41//! ```
42//!
43//! After `PathResolution`, all relevant paths are qualified with `foo::`:
44//! ```leo
45//! struct Bar { x: u32 }
46//! const Y: u32 = 1;
47//! transition t() { let z = foo::Bar { x: foo::Y }; }
48//! ```
49
50use crate::Pass;
51
52use leo_ast::ProgramReconstructor as _;
53use leo_errors::Result;
54
55mod ast;
56
57mod program;
58
59mod visitor;
60use visitor::*;
61
62pub struct PathResolution;
63
64impl Pass for PathResolution {
65    type Input = ();
66    type Output = ();
67
68    const NAME: &str = "PathResolution";
69
70    fn do_pass(_input: Self::Input, state: &mut crate::CompilerState) -> Result<Self::Output> {
71        let mut ast = std::mem::take(&mut state.ast);
72        let mut visitor = PathResolutionVisitor { state, module: Vec::new() };
73        ast.ast = visitor.reconstruct_program(ast.ast);
74        visitor.state.handler.last_err()?;
75        visitor.state.ast = ast;
76
77        Ok(())
78    }
79}