leo_span/
symbol.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 crate::source_map::SourceMap;
18
19use core::{
20    borrow::Borrow,
21    cmp::PartialEq,
22    fmt,
23    hash::{Hash, Hasher},
24    num::NonZeroU32,
25    ops::Deref,
26    str,
27};
28use fxhash::FxBuildHasher;
29use indexmap::IndexSet;
30use serde::{Deserialize, Deserializer, Serialize, Serializer};
31use std::cell::RefCell;
32
33/// A helper for `symbols` defined below.
34/// The macro's job is to bind conveniently usable `const` items to the symbol names provided.
35/// For example, with `symbol { a, b }` you'd have `sym::a` and `sym::b`.
36macro_rules! consts {
37    ($val: expr, $sym:ident $(,)?) => {
38        #[allow(non_upper_case_globals)]
39        pub const $sym: $crate::symbol::Symbol = $crate::symbol::Symbol::new($val);
40    };
41    ($val: expr, $sym:ident: $_s:literal $(,)?) => {
42        consts!($val, $sym);
43    };
44    ($val: expr, $sym:ident: $_s:literal, $($rest:tt)*) => {
45        consts!($val, $sym);
46        consts!($val + 1, $($rest)*);
47    };
48    ($val: expr, $sym:ident, $($rest:tt)*) => {
49        consts!($val, $sym);
50        consts!($val + 1, $($rest)*);
51    };
52}
53
54/// A helper for `symbols` defined below.
55/// The macro's job is to merge all the hard-coded strings into a single array of strings.
56/// The strategy applied is [push-down accumulation](https://danielkeep.github.io/tlborm/book/pat-push-down-accumulation.html).
57macro_rules! strings {
58    // Final step 0) in the push-down accumulation.
59    // Here, the actual strings gathered in `$acc` are made into an array.
60    // We have to use this approach because e.g., `$e1 , $e2` is not recognized by any syntactic
61    // category in Rust, so a macro cannot produce it.
62    ([$($acc:expr),*] []) => {
63        [$($acc),*]
64    };
65    // Recursive case 1): Handles e.g., `x: "frodo"` and `y: "sam"`
66    // in `symbols! { x: "frodo", y: "sam", z }`.
67    ([$($acc:expr),*] [$_sym:ident: $string:literal, $($rest:tt)*]) => {
68        strings!([$($acc,)* $string] [$($rest)*])
69    };
70    // Recursive case 2): Handles e.g., `x` and `y` in `symbols! { x, y, z }`.
71    ([$($acc:expr),*] [$sym:ident, $($rest:tt)*]) => {
72        strings!([$($acc,)* stringify!($sym)] [$($rest)*])
73    };
74    // Base case 3): As below, but with a specified string, e.g., `symbols! { x, y: "gandalf" }`.
75    ([$($acc:expr),*] [$_sym:ident: $string:literal $(,)?]) => {
76        strings!([$($acc,)* $string] [])
77    };
78    // Base case 4): A single identifier left.
79    // So in e.g., `symbols! { x, y }`, this handles `y` with `x` already in `$acc`.
80    ([$($acc:expr),*] [$sym:ident $(,)?]) => {
81        strings!([$($acc,)* stringify!($sym)] [])
82    };
83}
84
85/// Creates predefined symbols used throughout the Leo compiler and language.
86/// Broadly speaking, any hard-coded string in the compiler should be defined here.
87///
88/// The macro accepts symbols separated by commas,
89/// and a symbol is either specified as a Rust identifier, in which case it is `stringify!`ed,
90/// or as `ident: "string"` where `"string"` is the actual hard-coded string.
91/// The latter case can be used when the hard-coded string is not a valid identifier.
92/// In either case, a `const $ident: Symbol` will be created that you can access as `sym::$ident`.
93macro_rules! symbols {
94    ($($symbols:tt)*) => {
95        const PRE_DEFINED: &[&str] = &strings!([] [$($symbols)*]);
96
97        pub mod sym {
98            consts!(0, $($symbols)*);
99        }
100    };
101}
102
103symbols! {
104    // unary operators
105    abs,
106    abs_wrapped,
107    double,
108    inv,
109    neg,
110    not,
111    square,
112    square_root,
113
114    // binary operators
115    add,
116    add_wrapped,
117    and,
118    div,
119    div_wrapped,
120    eq,
121    gte,
122    gt,
123    lte,
124    lt,
125    Mod: "mod",
126    mul,
127    mul_wrapped,
128    nand,
129    neq,
130    nor,
131    or,
132    pow,
133    pow_wrapped,
134    rem,
135    rem_wrapped,
136    shl,
137    shl_wrapped,
138    shr,
139    shr_wrapped,
140    sub,
141    sub_wrapped,
142    xor,
143
144    // core constants
145    GEN,
146
147    // intrinsics
148    _group_gen,
149    _chacha_rand_address,
150    _chacha_rand_bool,
151    _chacha_rand_field,
152    _chacha_rand_group,
153    _chacha_rand_i8,
154    _chacha_rand_i16,
155    _chacha_rand_i32,
156    _chacha_rand_i64,
157    _chacha_rand_i128,
158    _chacha_rand_u8,
159    _chacha_rand_u16,
160    _chacha_rand_u32,
161    _chacha_rand_u64,
162    _chacha_rand_u128,
163    _chacha_rand_scalar,
164    _bhp256_commit_to_address,
165    _bhp256_commit_to_field,
166    _bhp256_commit_to_group,
167    _bhp512_commit_to_address,
168    _bhp512_commit_to_field,
169    _bhp512_commit_to_group,
170    _bhp768_commit_to_address,
171    _bhp768_commit_to_field,
172    _bhp768_commit_to_group,
173    _bhp1024_commit_to_address,
174    _bhp1024_commit_to_field,
175    _bhp1024_commit_to_group,
176    _pedersen64_commit_to_address,
177    _pedersen64_commit_to_field,
178    _pedersen64_commit_to_group,
179    _pedersen128_commit_to_address,
180    _pedersen128_commit_to_field,
181    _pedersen128_commit_to_group,
182    _bhp256_hash_to_address,
183    _bhp256_hash_to_field,
184    _bhp256_hash_to_group,
185    _bhp256_hash_to_i8,
186    _bhp256_hash_to_i16,
187    _bhp256_hash_to_i32,
188    _bhp256_hash_to_i64,
189    _bhp256_hash_to_i128,
190    _bhp256_hash_to_u8,
191    _bhp256_hash_to_u16,
192    _bhp256_hash_to_u32,
193    _bhp256_hash_to_u64,
194    _bhp256_hash_to_u128,
195    _bhp256_hash_to_scalar,
196    _bhp256_hash_to_address_raw,
197    _bhp256_hash_to_field_raw,
198    _bhp256_hash_to_group_raw,
199    _bhp256_hash_to_i8_raw,
200    _bhp256_hash_to_i16_raw,
201    _bhp256_hash_to_i32_raw,
202    _bhp256_hash_to_i64_raw,
203    _bhp256_hash_to_i128_raw,
204    _bhp256_hash_to_u8_raw,
205    _bhp256_hash_to_u16_raw,
206    _bhp256_hash_to_u32_raw,
207    _bhp256_hash_to_u64_raw,
208    _bhp256_hash_to_u128_raw,
209    _bhp256_hash_to_scalar_raw,
210    _bhp512_hash_to_address,
211    _bhp512_hash_to_field,
212    _bhp512_hash_to_group,
213    _bhp512_hash_to_i8,
214    _bhp512_hash_to_i16,
215    _bhp512_hash_to_i32,
216    _bhp512_hash_to_i64,
217    _bhp512_hash_to_i128,
218    _bhp512_hash_to_u8,
219    _bhp512_hash_to_u16,
220    _bhp512_hash_to_u32,
221    _bhp512_hash_to_u64,
222    _bhp512_hash_to_u128,
223    _bhp512_hash_to_scalar,
224    _bhp512_hash_to_address_raw,
225    _bhp512_hash_to_field_raw,
226    _bhp512_hash_to_group_raw,
227    _bhp512_hash_to_i8_raw,
228    _bhp512_hash_to_i16_raw,
229    _bhp512_hash_to_i32_raw,
230    _bhp512_hash_to_i64_raw,
231    _bhp512_hash_to_i128_raw,
232    _bhp512_hash_to_u8_raw,
233    _bhp512_hash_to_u16_raw,
234    _bhp512_hash_to_u32_raw,
235    _bhp512_hash_to_u64_raw,
236    _bhp512_hash_to_u128_raw,
237    _bhp512_hash_to_scalar_raw,
238    _bhp768_hash_to_address,
239    _bhp768_hash_to_field,
240    _bhp768_hash_to_group,
241    _bhp768_hash_to_i8,
242    _bhp768_hash_to_i16,
243    _bhp768_hash_to_i32,
244    _bhp768_hash_to_i64,
245    _bhp768_hash_to_i128,
246    _bhp768_hash_to_u8,
247    _bhp768_hash_to_u16,
248    _bhp768_hash_to_u32,
249    _bhp768_hash_to_u64,
250    _bhp768_hash_to_u128,
251    _bhp768_hash_to_scalar,
252    _bhp768_hash_to_address_raw,
253    _bhp768_hash_to_field_raw,
254    _bhp768_hash_to_group_raw,
255    _bhp768_hash_to_i8_raw,
256    _bhp768_hash_to_i16_raw,
257    _bhp768_hash_to_i32_raw,
258    _bhp768_hash_to_i64_raw,
259    _bhp768_hash_to_i128_raw,
260    _bhp768_hash_to_u8_raw,
261    _bhp768_hash_to_u16_raw,
262    _bhp768_hash_to_u32_raw,
263    _bhp768_hash_to_u64_raw,
264    _bhp768_hash_to_u128_raw,
265    _bhp768_hash_to_scalar_raw,
266    _bhp1024_hash_to_address,
267    _bhp1024_hash_to_field,
268    _bhp1024_hash_to_group,
269    _bhp1024_hash_to_i8,
270    _bhp1024_hash_to_i16,
271    _bhp1024_hash_to_i32,
272    _bhp1024_hash_to_i64,
273    _bhp1024_hash_to_i128,
274    _bhp1024_hash_to_u8,
275    _bhp1024_hash_to_u16,
276    _bhp1024_hash_to_u32,
277    _bhp1024_hash_to_u64,
278    _bhp1024_hash_to_u128,
279    _bhp1024_hash_to_scalar,
280    _bhp1024_hash_to_address_raw,
281    _bhp1024_hash_to_field_raw,
282    _bhp1024_hash_to_group_raw,
283    _bhp1024_hash_to_i8_raw,
284    _bhp1024_hash_to_i16_raw,
285    _bhp1024_hash_to_i32_raw,
286    _bhp1024_hash_to_i64_raw,
287    _bhp1024_hash_to_i128_raw,
288    _bhp1024_hash_to_u8_raw,
289    _bhp1024_hash_to_u16_raw,
290    _bhp1024_hash_to_u32_raw,
291    _bhp1024_hash_to_u64_raw,
292    _bhp1024_hash_to_u128_raw,
293    _bhp1024_hash_to_scalar_raw,
294    _keccak256_hash_to_address,
295    _keccak256_hash_to_field,
296    _keccak256_hash_to_group,
297    _keccak256_hash_to_i8,
298    _keccak256_hash_to_i16,
299    _keccak256_hash_to_i32,
300    _keccak256_hash_to_i64,
301    _keccak256_hash_to_i128,
302    _keccak256_hash_to_u8,
303    _keccak256_hash_to_u16,
304    _keccak256_hash_to_u32,
305    _keccak256_hash_to_u64,
306    _keccak256_hash_to_u128,
307    _keccak256_hash_to_scalar,
308    _keccak256_hash_to_address_raw,
309    _keccak256_hash_to_field_raw,
310    _keccak256_hash_to_group_raw,
311    _keccak256_hash_to_i8_raw,
312    _keccak256_hash_to_i16_raw,
313    _keccak256_hash_to_i32_raw,
314    _keccak256_hash_to_i64_raw,
315    _keccak256_hash_to_i128_raw,
316    _keccak256_hash_to_u8_raw,
317    _keccak256_hash_to_u16_raw,
318    _keccak256_hash_to_u32_raw,
319    _keccak256_hash_to_u64_raw,
320    _keccak256_hash_to_u128_raw,
321    _keccak256_hash_to_scalar_raw,
322    _keccak256_hash_to_bits,
323    _keccak256_hash_to_bits_raw,
324    _keccak384_hash_to_address,
325    _keccak384_hash_to_field,
326    _keccak384_hash_to_group,
327    _keccak384_hash_to_i8,
328    _keccak384_hash_to_i16,
329    _keccak384_hash_to_i32,
330    _keccak384_hash_to_i64,
331    _keccak384_hash_to_i128,
332    _keccak384_hash_to_u8,
333    _keccak384_hash_to_u16,
334    _keccak384_hash_to_u32,
335    _keccak384_hash_to_u64,
336    _keccak384_hash_to_u128,
337    _keccak384_hash_to_scalar,
338    _keccak384_hash_to_address_raw,
339    _keccak384_hash_to_field_raw,
340    _keccak384_hash_to_group_raw,
341    _keccak384_hash_to_i8_raw,
342    _keccak384_hash_to_i16_raw,
343    _keccak384_hash_to_i32_raw,
344    _keccak384_hash_to_i64_raw,
345    _keccak384_hash_to_i128_raw,
346    _keccak384_hash_to_u8_raw,
347    _keccak384_hash_to_u16_raw,
348    _keccak384_hash_to_u32_raw,
349    _keccak384_hash_to_u64_raw,
350    _keccak384_hash_to_u128_raw,
351    _keccak384_hash_to_scalar_raw,
352    _keccak384_hash_to_bits,
353    _keccak384_hash_to_bits_raw,
354    _keccak512_hash_to_address,
355    _keccak512_hash_to_field,
356    _keccak512_hash_to_group,
357    _keccak512_hash_to_i8,
358    _keccak512_hash_to_i16,
359    _keccak512_hash_to_i32,
360    _keccak512_hash_to_i64,
361    _keccak512_hash_to_i128,
362    _keccak512_hash_to_u8,
363    _keccak512_hash_to_u16,
364    _keccak512_hash_to_u32,
365    _keccak512_hash_to_u64,
366    _keccak512_hash_to_u128,
367    _keccak512_hash_to_scalar,
368    _keccak512_hash_to_address_raw,
369    _keccak512_hash_to_field_raw,
370    _keccak512_hash_to_group_raw,
371    _keccak512_hash_to_i8_raw,
372    _keccak512_hash_to_i16_raw,
373    _keccak512_hash_to_i32_raw,
374    _keccak512_hash_to_i64_raw,
375    _keccak512_hash_to_i128_raw,
376    _keccak512_hash_to_u8_raw,
377    _keccak512_hash_to_u16_raw,
378    _keccak512_hash_to_u32_raw,
379    _keccak512_hash_to_u64_raw,
380    _keccak512_hash_to_u128_raw,
381    _keccak512_hash_to_scalar_raw,
382    _keccak512_hash_to_bits,
383    _keccak512_hash_to_bits_raw,
384    _pedersen64_hash_to_address,
385    _pedersen64_hash_to_field,
386    _pedersen64_hash_to_group,
387    _pedersen64_hash_to_i8,
388    _pedersen64_hash_to_i16,
389    _pedersen64_hash_to_i32,
390    _pedersen64_hash_to_i64,
391    _pedersen64_hash_to_i128,
392    _pedersen64_hash_to_u8,
393    _pedersen64_hash_to_u16,
394    _pedersen64_hash_to_u32,
395    _pedersen64_hash_to_u64,
396    _pedersen64_hash_to_u128,
397    _pedersen64_hash_to_scalar,
398    _pedersen64_hash_to_address_raw,
399    _pedersen64_hash_to_field_raw,
400    _pedersen64_hash_to_group_raw,
401    _pedersen64_hash_to_i8_raw,
402    _pedersen64_hash_to_i16_raw,
403    _pedersen64_hash_to_i32_raw,
404    _pedersen64_hash_to_i64_raw,
405    _pedersen64_hash_to_i128_raw,
406    _pedersen64_hash_to_u8_raw,
407    _pedersen64_hash_to_u16_raw,
408    _pedersen64_hash_to_u32_raw,
409    _pedersen64_hash_to_u64_raw,
410    _pedersen64_hash_to_u128_raw,
411    _pedersen64_hash_to_scalar_raw,
412    _pedersen128_hash_to_address,
413    _pedersen128_hash_to_field,
414    _pedersen128_hash_to_group,
415    _pedersen128_hash_to_i8,
416    _pedersen128_hash_to_i16,
417    _pedersen128_hash_to_i32,
418    _pedersen128_hash_to_i64,
419    _pedersen128_hash_to_i128,
420    _pedersen128_hash_to_u8,
421    _pedersen128_hash_to_u16,
422    _pedersen128_hash_to_u32,
423    _pedersen128_hash_to_u64,
424    _pedersen128_hash_to_u128,
425    _pedersen128_hash_to_scalar,
426    _pedersen128_hash_to_address_raw,
427    _pedersen128_hash_to_field_raw,
428    _pedersen128_hash_to_group_raw,
429    _pedersen128_hash_to_i8_raw,
430    _pedersen128_hash_to_i16_raw,
431    _pedersen128_hash_to_i32_raw,
432    _pedersen128_hash_to_i64_raw,
433    _pedersen128_hash_to_i128_raw,
434    _pedersen128_hash_to_u8_raw,
435    _pedersen128_hash_to_u16_raw,
436    _pedersen128_hash_to_u32_raw,
437    _pedersen128_hash_to_u64_raw,
438    _pedersen128_hash_to_u128_raw,
439    _pedersen128_hash_to_scalar_raw,
440    _poseidon2_hash_to_address,
441    _poseidon2_hash_to_field,
442    _poseidon2_hash_to_group,
443    _poseidon2_hash_to_i8,
444    _poseidon2_hash_to_i16,
445    _poseidon2_hash_to_i32,
446    _poseidon2_hash_to_i64,
447    _poseidon2_hash_to_i128,
448    _poseidon2_hash_to_u8,
449    _poseidon2_hash_to_u16,
450    _poseidon2_hash_to_u32,
451    _poseidon2_hash_to_u64,
452    _poseidon2_hash_to_u128,
453    _poseidon2_hash_to_scalar,
454    _poseidon2_hash_to_address_raw,
455    _poseidon2_hash_to_field_raw,
456    _poseidon2_hash_to_group_raw,
457    _poseidon2_hash_to_i8_raw,
458    _poseidon2_hash_to_i16_raw,
459    _poseidon2_hash_to_i32_raw,
460    _poseidon2_hash_to_i64_raw,
461    _poseidon2_hash_to_i128_raw,
462    _poseidon2_hash_to_u8_raw,
463    _poseidon2_hash_to_u16_raw,
464    _poseidon2_hash_to_u32_raw,
465    _poseidon2_hash_to_u64_raw,
466    _poseidon2_hash_to_u128_raw,
467    _poseidon2_hash_to_scalar_raw,
468    _poseidon4_hash_to_address,
469    _poseidon4_hash_to_field,
470    _poseidon4_hash_to_group,
471    _poseidon4_hash_to_i8,
472    _poseidon4_hash_to_i16,
473    _poseidon4_hash_to_i32,
474    _poseidon4_hash_to_i64,
475    _poseidon4_hash_to_i128,
476    _poseidon4_hash_to_u8,
477    _poseidon4_hash_to_u16,
478    _poseidon4_hash_to_u32,
479    _poseidon4_hash_to_u64,
480    _poseidon4_hash_to_u128,
481    _poseidon4_hash_to_scalar,
482    _poseidon4_hash_to_address_raw,
483    _poseidon4_hash_to_field_raw,
484    _poseidon4_hash_to_group_raw,
485    _poseidon4_hash_to_i8_raw,
486    _poseidon4_hash_to_i16_raw,
487    _poseidon4_hash_to_i32_raw,
488    _poseidon4_hash_to_i64_raw,
489    _poseidon4_hash_to_i128_raw,
490    _poseidon4_hash_to_u8_raw,
491    _poseidon4_hash_to_u16_raw,
492    _poseidon4_hash_to_u32_raw,
493    _poseidon4_hash_to_u64_raw,
494    _poseidon4_hash_to_u128_raw,
495    _poseidon4_hash_to_scalar_raw,
496    _poseidon8_hash_to_address,
497    _poseidon8_hash_to_field,
498    _poseidon8_hash_to_group,
499    _poseidon8_hash_to_i8,
500    _poseidon8_hash_to_i16,
501    _poseidon8_hash_to_i32,
502    _poseidon8_hash_to_i64,
503    _poseidon8_hash_to_i128,
504    _poseidon8_hash_to_u8,
505    _poseidon8_hash_to_u16,
506    _poseidon8_hash_to_u32,
507    _poseidon8_hash_to_u64,
508    _poseidon8_hash_to_u128,
509    _poseidon8_hash_to_scalar,
510    _poseidon8_hash_to_address_raw,
511    _poseidon8_hash_to_field_raw,
512    _poseidon8_hash_to_group_raw,
513    _poseidon8_hash_to_i8_raw,
514    _poseidon8_hash_to_i16_raw,
515    _poseidon8_hash_to_i32_raw,
516    _poseidon8_hash_to_i64_raw,
517    _poseidon8_hash_to_i128_raw,
518    _poseidon8_hash_to_u8_raw,
519    _poseidon8_hash_to_u16_raw,
520    _poseidon8_hash_to_u32_raw,
521    _poseidon8_hash_to_u64_raw,
522    _poseidon8_hash_to_u128_raw,
523    _poseidon8_hash_to_scalar_raw,
524    _sha3_256_hash_to_address,
525    _sha3_256_hash_to_field,
526    _sha3_256_hash_to_group,
527    _sha3_256_hash_to_i8,
528    _sha3_256_hash_to_i16,
529    _sha3_256_hash_to_i32,
530    _sha3_256_hash_to_i64,
531    _sha3_256_hash_to_i128,
532    _sha3_256_hash_to_u8,
533    _sha3_256_hash_to_u16,
534    _sha3_256_hash_to_u32,
535    _sha3_256_hash_to_u64,
536    _sha3_256_hash_to_u128,
537    _sha3_256_hash_to_scalar,
538    _sha3_256_hash_to_address_raw,
539    _sha3_256_hash_to_field_raw,
540    _sha3_256_hash_to_group_raw,
541    _sha3_256_hash_to_i8_raw,
542    _sha3_256_hash_to_i16_raw,
543    _sha3_256_hash_to_i32_raw,
544    _sha3_256_hash_to_i64_raw,
545    _sha3_256_hash_to_i128_raw,
546    _sha3_256_hash_to_u8_raw,
547    _sha3_256_hash_to_u16_raw,
548    _sha3_256_hash_to_u32_raw,
549    _sha3_256_hash_to_u64_raw,
550    _sha3_256_hash_to_u128_raw,
551    _sha3_256_hash_to_scalar_raw,
552    _sha3_256_hash_to_bits,
553    _sha3_256_hash_to_bits_raw,
554    _sha3_384_hash_to_address,
555    _sha3_384_hash_to_field,
556    _sha3_384_hash_to_group,
557    _sha3_384_hash_to_i8,
558    _sha3_384_hash_to_i16,
559    _sha3_384_hash_to_i32,
560    _sha3_384_hash_to_i64,
561    _sha3_384_hash_to_i128,
562    _sha3_384_hash_to_u8,
563    _sha3_384_hash_to_u16,
564    _sha3_384_hash_to_u32,
565    _sha3_384_hash_to_u64,
566    _sha3_384_hash_to_u128,
567    _sha3_384_hash_to_scalar,
568    _sha3_384_hash_to_address_raw,
569    _sha3_384_hash_to_field_raw,
570    _sha3_384_hash_to_group_raw,
571    _sha3_384_hash_to_i8_raw,
572    _sha3_384_hash_to_i16_raw,
573    _sha3_384_hash_to_i32_raw,
574    _sha3_384_hash_to_i64_raw,
575    _sha3_384_hash_to_i128_raw,
576    _sha3_384_hash_to_u8_raw,
577    _sha3_384_hash_to_u16_raw,
578    _sha3_384_hash_to_u32_raw,
579    _sha3_384_hash_to_u64_raw,
580    _sha3_384_hash_to_u128_raw,
581    _sha3_384_hash_to_scalar_raw,
582    _sha3_384_hash_to_bits,
583    _sha3_384_hash_to_bits_raw,
584    _sha3_512_hash_to_address,
585    _sha3_512_hash_to_field,
586    _sha3_512_hash_to_group,
587    _sha3_512_hash_to_i8,
588    _sha3_512_hash_to_i16,
589    _sha3_512_hash_to_i32,
590    _sha3_512_hash_to_i64,
591    _sha3_512_hash_to_i128,
592    _sha3_512_hash_to_u8,
593    _sha3_512_hash_to_u16,
594    _sha3_512_hash_to_u32,
595    _sha3_512_hash_to_u64,
596    _sha3_512_hash_to_u128,
597    _sha3_512_hash_to_scalar,
598    _sha3_512_hash_to_address_raw,
599    _sha3_512_hash_to_field_raw,
600    _sha3_512_hash_to_group_raw,
601    _sha3_512_hash_to_i8_raw,
602    _sha3_512_hash_to_i16_raw,
603    _sha3_512_hash_to_i32_raw,
604    _sha3_512_hash_to_i64_raw,
605    _sha3_512_hash_to_i128_raw,
606    _sha3_512_hash_to_u8_raw,
607    _sha3_512_hash_to_u16_raw,
608    _sha3_512_hash_to_u32_raw,
609    _sha3_512_hash_to_u64_raw,
610    _sha3_512_hash_to_u128_raw,
611    _sha3_512_hash_to_scalar_raw,
612    _sha3_512_hash_to_bits,
613    _sha3_512_hash_to_bits_raw,
614    _ecdsa_verify_digest,
615    _ecdsa_verify_digest_eth,
616    _ecdsa_verify_keccak256,
617    _ecdsa_verify_keccak256_raw,
618    _ecdsa_verify_keccak256_eth,
619    _ecdsa_verify_keccak384,
620    _ecdsa_verify_keccak384_raw,
621    _ecdsa_verify_keccak384_eth,
622    _ecdsa_verify_keccak512,
623    _ecdsa_verify_keccak512_raw,
624    _ecdsa_verify_keccak512_eth,
625    _ecdsa_verify_sha3_256,
626    _ecdsa_verify_sha3_256_raw,
627    _ecdsa_verify_sha3_256_eth,
628    _ecdsa_verify_sha3_384,
629    _ecdsa_verify_sha3_384_raw,
630    _ecdsa_verify_sha3_384_eth,
631    _ecdsa_verify_sha3_512,
632    _ecdsa_verify_sha3_512_raw,
633    _ecdsa_verify_sha3_512_eth,
634    _mapping_get,
635    _mapping_set,
636    _mapping_get_or_use,
637    _mapping_remove,
638    _mapping_contains,
639    _optional_unwrap,
640    _optional_unwrap_or,
641    _vector_get,
642    _vector_set,
643    _vector_push,
644    _vector_len,
645    _vector_clear,
646    _vector_pop,
647    _vector_swap_remove,
648    _group_to_x_coordinate,
649    _group_to_y_coordinate,
650    _program_checksum,
651    _program_edition,
652    _program_owner,
653    _signature_verify,
654    _future_await,
655    _serialize_to_bits,
656    _serialize_to_bits_raw,
657    _deserialize_from_bits,
658    _deserialize_from_bits_raw,
659    _cheat_code_print_mapping,
660    _cheat_code_set_block_height,
661    _cheat_code_set_block_timestamp,
662    _cheat_code_set_signer,
663    _self_address,
664    _self_caller,
665    _self_checksum,
666    _self_edition,
667    _self_id,
668    _self_program_owner,
669    _self_signer,
670    _block_height,
671    _block_timestamp,
672    _network_id,
673
674
675    // core functions
676    BHP256,
677    BHP512,
678    BHP768,
679    BHP1024,
680    ChaCha,
681    commit_to_address,
682    commit_to_field,
683    commit_to_group,
684    contains,
685    ECDSA,
686    get,
687    get_or_use,
688    hash_to_address,
689    hash_to_field,
690    hash_to_group,
691    hash_to_i8,
692    hash_to_i16,
693    hash_to_i32,
694    hash_to_i64,
695    hash_to_i128,
696    hash_to_u8,
697    hash_to_u16,
698    hash_to_u32,
699    hash_to_u64,
700    hash_to_u128,
701    hash_to_scalar,
702    hash_to_address_raw,
703    hash_to_field_raw,
704    hash_to_group_raw,
705    hash_to_i8_raw,
706    hash_to_i16_raw,
707    hash_to_i32_raw,
708    hash_to_i64_raw,
709    hash_to_i128_raw,
710    hash_to_u8_raw,
711    hash_to_u16_raw,
712    hash_to_u32_raw,
713    hash_to_u64_raw,
714    hash_to_u128_raw,
715    hash_to_scalar_raw,
716    hash_to_bits,
717    hash_to_bits_raw,
718    Keccak256,
719    Keccak384,
720    Keccak512,
721    Mapping,
722    Storage,
723    Optional,
724    Vector,
725    Pedersen64,
726    Pedersen128,
727    Poseidon2,
728    Poseidon4,
729    Poseidon8,
730    rand_address,
731    rand_bool,
732    rand_field,
733    rand_group,
734    rand_i8,
735    rand_i16,
736    rand_i32,
737    rand_i64,
738    rand_i128,
739    rand_scalar,
740    rand_u8,
741    rand_u16,
742    rand_u32,
743    rand_u64,
744    rand_u128,
745    remove,
746    set,
747    SHA3_256,
748    SHA3_384,
749    SHA3_512,
750    to_x_coordinate,
751    to_y_coordinate,
752    verify,
753    verify_digest,
754    verify_digest_eth,
755    verify_keccak256,
756    verify_keccak256_raw,
757    verify_keccak256_eth,
758    verify_keccak256_eth_raw,
759    verify_keccak384,
760    verify_keccak384_raw,
761    verify_keccak384_eth,
762    verify_keccak384_eth_raw,
763    verify_keccak512,
764    verify_keccak512_raw,
765    verify_keccak512_eth,
766    verify_keccak512_eth_raw,
767    verify_sha3_256,
768    verify_sha3_256_raw,
769    verify_sha3_256_eth,
770    verify_sha3_256_eth_raw,
771    verify_sha3_384,
772    verify_sha3_384_raw,
773    verify_sha3_384_eth,
774    verify_sha3_384_eth_raw,
775    verify_sha3_512,
776    verify_sha3_512_raw,
777    verify_sha3_512_eth,
778    verify_sha3_512_eth_raw,
779    Serialize,
780    Deserialize,
781    to_bits,
782    to_bits_raw,
783    from_bits,
784    from_bits_raw,
785
786    Await: "await",
787    unwrap,
788    unwrap_or,
789    push,
790    len,
791    clear,
792    pop,
793    swap_remove,
794
795    // CheatCodes
796    CheatCode,
797    print_mapping,
798    set_block_height,
799    set_block_timestamp,
800    set_signer,
801
802    // types
803    address,
804    bool,
805    field,
806    group,
807    i8,
808    i16,
809    i32,
810    i64,
811    i128,
812    Future,
813    Fn,
814    record,
815    scalar,
816    signature,
817    string,
818    Struct: "struct",
819    u8,
820    u16,
821    u32,
822    u64,
823    u128,
824
825    // values
826    False: "false",
827    True: "true",
828    None: "none",
829
830    // annotations
831    should_fail,
832    test,
833    noupgrade,
834    custom,
835    admin,
836    key,
837
838    // annotation keys
839    private_key,
840
841    // general keywords
842    As: "as",
843    assert,
844    assert_eq,
845    assert_neq,
846    Async: "async",
847    caller,
848    Const: "const",
849    constant,
850    constructor,
851    decrement,
852    Else: "else",
853    For: "for",
854    function,
855    If: "if",
856    In: "in",
857    import,
858    increment,
859    inline,
860    input,
861    Let: "let",
862    leo,
863    main,
864    mapping,
865    storage,
866    Mut: "mut",
867    Return: "return",
868    script,
869    SelfLower: "self",
870    SelfUpper: "Self",
871    signer,
872    Star: "*",
873    transition,
874    Type: "type",
875
876    aleo,
877    public,
878    private,
879    owner,
880    _nonce,
881    program,
882    ProgramCore: "Program",
883    stub,
884    block,
885    height,
886    timestamp,
887    network,
888    id,
889    checksum,
890    edition,
891    program_owner,
892}
893
894/// An interned string.
895///
896/// Represented as an index internally, with all operations based on that.
897/// A `Symbol` reserves the value `0`, so that `Option<Symbol>` only takes up 4 bytes.
898#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
899pub struct Symbol(
900    #[serde(deserialize_with = "Symbol::serde_to_symbol")]
901    #[serde(serialize_with = "Symbol::serde_from_symbol")]
902    NonZeroU32,
903);
904
905impl Default for Symbol {
906    fn default() -> Self {
907        Symbol(NonZeroU32::MIN)
908    }
909}
910
911impl Symbol {
912    /// Returns the corresponding `Symbol` for the given `index`.
913    pub const fn new(index: u32) -> Self {
914        let index = index.saturating_add(1);
915        Self(match NonZeroU32::new(index) {
916            None => unreachable!(),
917            Some(x) => x,
918        })
919    }
920
921    /// Maps a string to its interned representation.
922    pub fn intern(string: &str) -> Self {
923        with_session_globals(|session_globals| session_globals.symbol_interner.intern(string))
924    }
925
926    /// Convert to effectively a `&'static str` given the `SessionGlobals`.
927    pub fn as_str<R>(self, s: &SessionGlobals, with: impl FnOnce(&str) -> R) -> R {
928        s.symbol_interner.get(self, with)
929    }
930
931    /// Converts this symbol to the raw index.
932    pub const fn as_u32(self) -> u32 {
933        self.0.get() - 1
934    }
935
936    fn serde_to_symbol<'de, D: Deserializer<'de>>(de: D) -> Result<NonZeroU32, D::Error> {
937        Ok(Symbol::intern(<&str>::deserialize(de)?).0)
938    }
939
940    fn serde_from_symbol<S: Serializer>(index: &NonZeroU32, ser: S) -> Result<S::Ok, S::Error> {
941        with_session_globals(|sg| Self(*index).as_str(sg, |s| ser.serialize_str(s)))
942    }
943}
944
945impl fmt::Debug for Symbol {
946    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
947        with_session_globals(|s| self.as_str(s, |s| fmt::Debug::fmt(s, f)))
948    }
949}
950
951impl fmt::Display for Symbol {
952    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
953        with_session_globals(|s| self.as_str(s, |s| fmt::Display::fmt(s, f)))
954    }
955}
956
957/// All the globals for a compiler sessions.
958pub struct SessionGlobals {
959    /// The interner for `Symbol`s used in the compiler.
960    symbol_interner: Interner,
961    /// The source map used in the compiler.
962    pub source_map: SourceMap,
963}
964
965impl Default for SessionGlobals {
966    fn default() -> Self {
967        Self { symbol_interner: Interner::prefilled(), source_map: SourceMap::default() }
968    }
969}
970
971scoped_tls::scoped_thread_local!(pub static SESSION_GLOBALS: SessionGlobals);
972
973/// Creates the session globals and then runs the closure `f`.
974#[inline]
975pub fn create_session_if_not_set_then<R>(f: impl FnOnce(&SessionGlobals) -> R) -> R {
976    if !SESSION_GLOBALS.is_set() {
977        let sg = SessionGlobals::default();
978        SESSION_GLOBALS.set(&sg, || SESSION_GLOBALS.with(f))
979    } else {
980        SESSION_GLOBALS.with(f)
981    }
982}
983
984/// Gives access to read or modify the session globals in `f`.
985#[inline]
986pub fn with_session_globals<R>(f: impl FnOnce(&SessionGlobals) -> R) -> R {
987    SESSION_GLOBALS.with(f)
988}
989
990/// An interned string,
991/// either prefilled "at compile time" (`Static`),
992/// or created at runtime (`Owned`).
993#[derive(Eq)]
994enum InternedStr {
995    /// String is stored "at compile time", i.e. prefilled.
996    Static(&'static str),
997    /// String is constructed and stored during runtime.
998    Owned(Box<str>),
999}
1000
1001impl Borrow<str> for InternedStr {
1002    fn borrow(&self) -> &str {
1003        self.deref()
1004    }
1005}
1006
1007impl Deref for InternedStr {
1008    type Target = str;
1009
1010    fn deref(&self) -> &Self::Target {
1011        match self {
1012            Self::Static(s) => s,
1013            Self::Owned(s) => s,
1014        }
1015    }
1016}
1017
1018impl PartialEq for InternedStr {
1019    fn eq(&self, other: &InternedStr) -> bool {
1020        self.deref() == other.deref()
1021    }
1022}
1023
1024impl Hash for InternedStr {
1025    fn hash<H: Hasher>(&self, state: &mut H) {
1026        self.deref().hash(state);
1027    }
1028}
1029
1030/// The inner interner.
1031/// This construction is used to get interior mutability in `Interner`.
1032struct InnerInterner {
1033    // /// Arena used to allocate the strings, giving us `&'static str`s from it.
1034    // arena: DroplessArena,
1035    /// Registration of strings and symbol index allocation is done in this set.
1036    set: IndexSet<InternedStr, FxBuildHasher>,
1037}
1038
1039/// A symbol-to-string interner.
1040struct Interner {
1041    inner: RefCell<InnerInterner>,
1042}
1043
1044impl Interner {
1045    /// Returns an interner prefilled with commonly used strings in Leo.
1046    fn prefilled() -> Self {
1047        Self::prefill(PRE_DEFINED)
1048    }
1049
1050    /// Returns an interner prefilled with `init`.
1051    fn prefill(init: &[&'static str]) -> Self {
1052        let inner = InnerInterner {
1053            // arena: <_>::default(),
1054            set: init.iter().copied().map(InternedStr::Static).collect(),
1055        };
1056        Self { inner: RefCell::new(inner) }
1057    }
1058
1059    /// Interns `string`, returning a `Symbol` corresponding to it.
1060    fn intern(&self, string: &str) -> Symbol {
1061        let InnerInterner { set } = &mut *self.inner.borrow_mut();
1062
1063        if let Some(sym) = set.get_index_of(string) {
1064            // Already interned, return that symbol.
1065            return Symbol::new(sym as u32);
1066        }
1067
1068        Symbol::new(set.insert_full(InternedStr::Owned(string.into())).0 as u32)
1069    }
1070
1071    /// Returns the corresponding string for the given symbol.
1072    fn get<R>(&self, symbol: Symbol, with: impl FnOnce(&str) -> R) -> R {
1073        let set = &self.inner.borrow().set;
1074        with(set.get_index(symbol.as_u32() as usize).unwrap())
1075    }
1076}