leo_passes/code_generation/
type_.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
17use super::*;
18
19use leo_ast::{CompositeType, Location, Mode, Type};
20
21impl CodeGeneratingVisitor<'_> {
22    pub fn visit_type(input: &Type) -> String {
23        match input {
24            Type::Address
25            | Type::Field
26            | Type::Group
27            | Type::Scalar
28            | Type::Signature
29            | Type::String
30            | Type::Future(..)
31            | Type::Identifier(..)
32            | Type::Integer(..) => format!("{input}"),
33            Type::Composite(CompositeType { path, .. }) => {
34                Self::legalize_path(&path.absolute_path()).expect("path format cannot be legalized at this point")
35            }
36            Type::Boolean => {
37                // Leo calls this just `bool`, which isn't what we need.
38                "boolean".into()
39            }
40            Type::Array(array_type) => {
41                format!(
42                    "[{}; {}u32]",
43                    Self::visit_type(array_type.element_type()),
44                    array_type.length.as_u32().expect("length should be known at this point")
45                )
46            }
47            Type::Optional(_) => {
48                panic!("Optional types are not supported at this phase of compilation")
49            }
50            Type::Mapping(_) => {
51                panic!("Mapping types are not supported at this phase of compilation")
52            }
53            Type::Tuple(_) => {
54                panic!("Tuple types should not be visited at this phase of compilation")
55            }
56            Type::Numeric => panic!("`Numeric` types should not exist at this phase of compilation"),
57            Type::Err => panic!("Error types should not exist at this phase of compilation"),
58            Type::Unit => panic!("Unit types are not supported at this phase of compilation"),
59        }
60    }
61
62    pub fn visit_type_with_visibility(&self, type_: &Type, visibility: Mode) -> String {
63        // If the type is a record, handle it separately.
64        if let Type::Composite(composite) = type_ {
65            let name = composite.path.absolute_path();
66            let this_program_name = self.program_id.unwrap().name.name;
67            let program_name = composite.program.unwrap_or(this_program_name);
68            if self.state.symbol_table.lookup_record(&Location::new(program_name, name.to_vec())).is_some() {
69                let [record_name] = &name[..] else {
70                    panic!("Absolute paths to records can only have a single segment at this stage.")
71                };
72                if program_name == this_program_name {
73                    return format!("{record_name}.record");
74                } else {
75                    return format!("{program_name}.aleo/{record_name}.record");
76                }
77            }
78        }
79
80        if let Mode::None = visibility {
81            Self::visit_type(type_)
82        } else {
83            format!("{}.{visibility}", Self::visit_type(type_))
84        }
85    }
86}