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, IntegerType, Location, Type};
20
21impl CodeGeneratingVisitor<'_> {
22    pub fn visit_type(input: &Type) -> AleoType {
23        match input {
24            Type::Address => AleoType::Address,
25            Type::Field => AleoType::Field,
26            Type::Group => AleoType::Group,
27            Type::Scalar => AleoType::Scalar,
28            Type::Signature => AleoType::Signature,
29            Type::String => AleoType::String,
30
31            Type::Integer(int) => match int {
32                IntegerType::U8 => AleoType::U8,
33                IntegerType::U16 => AleoType::U16,
34                IntegerType::U32 => AleoType::U32,
35                IntegerType::U64 => AleoType::U64,
36                IntegerType::U128 => AleoType::U128,
37                IntegerType::I8 => AleoType::I8,
38                IntegerType::I16 => AleoType::I16,
39                IntegerType::I32 => AleoType::I32,
40                IntegerType::I64 => AleoType::I64,
41                IntegerType::I128 => AleoType::I128,
42            },
43            Type::Identifier(id) => AleoType::Ident { name: id.to_string() },
44            Type::Composite(CompositeType { path, .. }) => AleoType::Ident {
45                name: Self::legalize_path(&path.absolute_path())
46                    .expect("path format cannot be legalized at this point"),
47            },
48            Type::Boolean => AleoType::Boolean,
49            Type::Array(array_type) => AleoType::Array {
50                inner: Box::new(Self::visit_type(array_type.element_type())),
51                len: array_type.length.as_u32().expect("length should be known at this point"),
52            },
53            Type::Future(..) => {
54                panic!("Future types should not be visited at this phase of compilation")
55            }
56            Type::Optional(_) => {
57                panic!("Optional types are not supported at this phase of compilation")
58            }
59            Type::Mapping(_) => {
60                panic!("Mapping types are not supported at this phase of compilation")
61            }
62            Type::Tuple(_) => {
63                panic!("Tuple types should not be visited at this phase of compilation")
64            }
65            Type::Vector(_) => {
66                panic!("Vector types should not be visited at this phase of compilation")
67            }
68            Type::Numeric => panic!("`Numeric` types should not exist at this phase of compilation"),
69            Type::Err => panic!("Error types should not exist at this phase of compilation"),
70            Type::Unit => panic!("Unit types are not supported at this phase of compilation"),
71        }
72    }
73
74    pub fn visit_type_with_visibility(
75        &self,
76        type_: &Type,
77        visibility: Option<AleoVisibility>,
78    ) -> (AleoType, Option<AleoVisibility>) {
79        // If the type is a record, handle it separately.
80        if let Type::Composite(composite) = type_ {
81            let name = composite.path.absolute_path();
82            let this_program_name = self.program_id.unwrap().name.name;
83            let program_name = composite.program.unwrap_or(this_program_name);
84            if self.state.symbol_table.lookup_record(&Location::new(program_name, name.to_vec())).is_some() {
85                let [record_name] = &name[..] else {
86                    panic!("Absolute paths to records can only have a single segment at this stage.")
87                };
88                if program_name == this_program_name {
89                    return (AleoType::Record { name: record_name.to_string(), program: None }, None);
90                } else {
91                    return (
92                        AleoType::Record { name: record_name.to_string(), program: Some(program_name.to_string()) },
93                        None,
94                    );
95                }
96            }
97        }
98
99        (Self::visit_type(type_), visibility)
100    }
101}