1use super::{CompletedMarker, Parser};
29use crate::syntax_kind::SyntaxKind::*;
30
31#[derive(Default, Clone, Copy)]
33pub struct TypeOpts {
34 pub allow_optional: bool,
36}
37
38impl TypeOpts {
39 pub fn allow_optional(mut self) -> Self {
41 self.allow_optional = true;
42 self
43 }
44}
45
46impl Parser<'_, '_> {
47 pub const PRIMITIVE_TYPE_KINDS: &'static [crate::syntax_kind::SyntaxKind] = &[
49 KW_ADDRESS,
50 KW_BOOL,
51 KW_FIELD,
52 KW_GROUP,
53 KW_SCALAR,
54 KW_SIGNATURE,
55 KW_STRING,
56 KW_IDENTIFIER,
57 KW_DYN,
58 KW_I8,
59 KW_I16,
60 KW_I32,
61 KW_I64,
62 KW_I128,
63 KW_U8,
64 KW_U16,
65 KW_U32,
66 KW_U64,
67 KW_U128,
68 ];
69
70 pub fn parse_type(&mut self) -> Option<CompletedMarker> {
74 self.parse_type_with_opts(TypeOpts::default().allow_optional())
75 }
76
77 pub fn parse_type_with_opts(&mut self, opts: TypeOpts) -> Option<CompletedMarker> {
79 let ty = self.parse_type_inner()?;
80
81 if opts.allow_optional && self.at(QUESTION) {
83 let m = ty.precede(self);
84 self.bump_any(); return Some(m.complete(self, TYPE_OPTIONAL));
86 }
87
88 Some(ty)
89 }
90
91 fn parse_type_inner(&mut self) -> Option<CompletedMarker> {
93 self.skip_trivia();
95
96 match self.current() {
97 L_PAREN => self.parse_tuple_type(),
99 L_BRACKET => self.parse_array_or_vector_type(),
101 KW_FINAL_UPPER => self.parse_future_type(),
103 KW_MAPPING => self.parse_mapping_type(),
105 KW_DYN => self.parse_dyn_record_type(),
107 _ if self.at_primitive_type() => self.parse_primitive_type(),
109 IDENT => self.parse_named_type(),
111 _ => None,
112 }
113 }
114
115 fn at_primitive_type(&self) -> bool {
117 Self::PRIMITIVE_TYPE_KINDS.contains(&self.current())
118 }
119
120 pub fn parse_cast_type(&mut self) -> Option<CompletedMarker> {
122 if self.at_primitive_type() {
123 self.parse_primitive_type()
124 } else if self.at(KW_DYN) {
125 self.parse_dyn_record_type()
126 } else {
127 None
128 }
129 }
130
131 fn parse_primitive_type(&mut self) -> Option<CompletedMarker> {
133 if !self.at_primitive_type() {
134 return None;
135 }
136
137 self.skip_trivia();
140 let m = self.start();
141 let kind = self.current();
142 self.bump_raw();
143 if kind == KW_DYN {
145 self.expect(KW_RECORD);
146 }
147 Some(m.complete(self, TYPE_PRIMITIVE))
148 }
149
150 fn parse_dyn_record_type(&mut self) -> Option<CompletedMarker> {
152 if !self.at(KW_DYN) {
153 return None;
154 }
155 self.skip_trivia();
156 let m = self.start();
157 self.bump_any(); if !self.eat(KW_RECORD) {
160 self.error("expected `record` after `dyn`");
161 }
162 Some(m.complete(self, TYPE_DYN_RECORD))
163 }
164
165 fn parse_tuple_type(&mut self) -> Option<CompletedMarker> {
167 if !self.at(L_PAREN) {
168 return None;
169 }
170
171 let m = self.start();
172 self.bump_any(); if self.eat(R_PAREN) {
176 return Some(m.complete(self, TYPE_TUPLE));
177 }
178
179 self.parse_type_with_opts(TypeOpts::default().allow_optional());
181
182 while self.eat(COMMA) {
184 if self.at(R_PAREN) {
185 break;
187 }
188 self.parse_type_with_opts(TypeOpts::default().allow_optional());
189 }
190
191 self.expect(R_PAREN);
192 Some(m.complete(self, TYPE_TUPLE))
193 }
194
195 fn parse_array_or_vector_type(&mut self) -> Option<CompletedMarker> {
197 if !self.at(L_BRACKET) {
198 return None;
199 }
200
201 let m = self.start();
202 self.bump_any(); self.parse_type_with_opts(TypeOpts::default().allow_optional());
206
207 if self.eat(SEMICOLON) {
209 let len = self.start();
211 self.parse_array_length();
212 len.complete(self, ARRAY_LENGTH);
213 self.expect(R_BRACKET);
214 return Some(m.complete(self, TYPE_ARRAY));
215 }
216
217 if self.at(COMMA) {
219 self.error("expected ';' for array type, found ','");
220 self.recover(&[R_BRACKET]);
221 self.eat(R_BRACKET);
222 return Some(m.complete(self, TYPE_ARRAY));
223 }
224
225 self.expect(R_BRACKET);
227 Some(m.complete(self, TYPE_VECTOR))
228 }
229
230 fn parse_array_length(&mut self) {
235 self.parse_expr();
236 }
237
238 fn parse_future_type(&mut self) -> Option<CompletedMarker> {
240 if !self.at(KW_FINAL_UPPER) {
241 return None;
242 }
243
244 let m = self.start();
245 self.bump_any(); if self.eat(LT) {
249 self.expect(KW_FN_UPPER);
251 self.expect(L_PAREN);
252
253 if !self.at(R_PAREN) {
255 self.parse_type_with_opts(TypeOpts::default().allow_optional());
256 while self.eat(COMMA) {
257 if self.at(R_PAREN) {
258 break;
259 }
260 self.parse_type_with_opts(TypeOpts::default().allow_optional());
261 }
262 }
263
264 self.expect(R_PAREN);
265
266 if self.eat(ARROW) {
268 self.parse_type_with_opts(TypeOpts::default().allow_optional());
269 }
270
271 self.expect(GT);
272 }
273
274 Some(m.complete(self, TYPE_FINAL))
275 }
276
277 fn parse_mapping_type(&mut self) -> Option<CompletedMarker> {
279 if !self.at(KW_MAPPING) {
280 return None;
281 }
282
283 let m = self.start();
284 self.bump_any(); self.parse_type();
288
289 self.expect(FAT_ARROW);
291
292 self.parse_type();
294
295 Some(m.complete(self, TYPE_MAPPING))
296 }
297
298 fn parse_named_type(&mut self) -> Option<CompletedMarker> {
306 if !self.at(IDENT) {
307 return None;
308 }
309
310 let m = self.start();
311 self.bump_any(); if self.at(DOT) && self.nth(1) == KW_ALEO {
315 self.bump_any(); self.bump_any(); if self.eat(COLON_COLON) {
319 if self.at(IDENT) {
321 self.bump_any();
322 while self.at(COLON_COLON) && self.nth(1) == IDENT {
324 self.bump_any(); self.bump_any(); }
327 } else {
328 self.error("expected type name after ::");
329 }
330 }
331
332 if self.at(COLON_COLON) && self.nth(1) == L_BRACKET {
334 self.bump_any(); self.parse_const_generic_args_bracket();
336 }
337
338 return Some(m.complete(self, TYPE_LOCATOR));
339 }
340
341 while self.eat(COLON_COLON) {
343 if self.at(L_BRACKET) {
344 self.parse_const_generic_args_bracket();
346 break;
347 } else if self.at(LT) {
348 self.parse_const_generic_args_angle();
350 break;
351 } else if self.at(IDENT) {
352 self.bump_any();
353 } else {
354 self.error("expected identifier, [, or < after ::");
355 break;
356 }
357 }
358
359 Some(m.complete(self, TYPE_PATH))
360 }
361
362 pub fn parse_const_param_list(&mut self) {
367 let m = self.start();
368
369 if !self.eat(L_BRACKET) {
370 m.abandon(self);
371 return;
372 }
373
374 if !self.at(R_BRACKET) {
376 self.parse_const_param();
377 while self.eat(COMMA) {
378 if self.at(R_BRACKET) {
379 break;
380 }
381 self.parse_const_param();
382 }
383 }
384
385 self.expect(R_BRACKET);
386 m.complete(self, CONST_PARAM_LIST);
387 }
388
389 fn parse_const_param(&mut self) {
391 let m = self.start();
392 self.skip_trivia();
393
394 if self.at(IDENT) {
395 self.bump_any(); } else {
397 self.error("expected const parameter name");
398 }
399
400 self.expect(COLON);
401 self.parse_type();
402
403 m.complete(self, CONST_PARAM);
404 }
405
406 pub fn parse_const_generic_args_bracket(&mut self) {
411 let m = self.start();
412
413 if !self.eat(L_BRACKET) {
414 m.abandon(self);
415 return;
416 }
417
418 if !self.at(R_BRACKET) {
420 self.parse_const_generic_arg();
421 while self.eat(COMMA) {
422 if self.at(R_BRACKET) {
423 break;
424 }
425 self.erroring = false;
427 self.parse_const_generic_arg();
428 }
429 }
430
431 self.expect(R_BRACKET);
432 m.complete(self, CONST_ARG_LIST);
433 }
434
435 pub fn parse_const_generic_args_angle(&mut self) {
441 let m = self.start();
442
443 if !self.eat(LT) {
444 m.abandon(self);
445 return;
446 }
447
448 if self.at(IDENT) || self.at(INTEGER) {
450 self.bump_any();
451 }
452
453 while self.eat(COMMA) {
454 if self.at(GT) {
455 break;
456 }
457 if self.at(IDENT) || self.at(INTEGER) {
458 self.bump_any();
459 } else {
460 self.error("expected const generic argument");
461 break;
462 }
463 }
464
465 self.expect(GT);
466 m.complete(self, CONST_ARG_LIST);
467 }
468
469 fn parse_const_generic_arg(&mut self) {
477 self.skip_trivia();
478 if matches!(self.current(), KW_PUBLIC | KW_PRIVATE | KW_CONSTANT) {
479 let m = self.start();
481 self.bump_any(); self.parse_type();
483 m.complete(self, DYNAMIC_CALL_RETURN_TYPE);
484 } else if self.at_primitive_type() {
485 self.parse_type();
487 } else if self.at(L_BRACKET) && self.nth(1).is_type_keyword() {
488 self.parse_type();
490 } else if self.at(KW_FINAL_UPPER) {
491 self.parse_type();
493 } else if self.at(KW_DYN) {
494 self.parse_type();
496 } else if self.at(L_PAREN) && (self.nth(1) == R_PAREN || Self::PRIMITIVE_TYPE_KINDS.contains(&self.nth(1))) {
497 self.parse_type();
501 } else {
502 self.parse_expr();
504 }
505 }
506}
507
508#[cfg(test)]
509mod tests {
510 use super::*;
511 use crate::{lexer::lex, parser::Parse};
512 use expect_test::{Expect, expect};
513
514 fn check_type(input: &str, expect: Expect) {
515 let (tokens, _) = lex(input);
516 let mut parser = Parser::new(input, &tokens);
517 let root = parser.start();
518 parser.parse_type();
519 parser.skip_trivia();
520 root.complete(&mut parser, ROOT);
521 let parse: Parse = parser.finish(vec![]);
522 let output = format!("{:#?}", parse.syntax());
523 expect.assert_eq(&output);
524 }
525
526 fn check_type_optional(input: &str, expect: Expect) {
527 let (tokens, _) = lex(input);
528 let mut parser = Parser::new(input, &tokens);
529 let root = parser.start();
530 parser.parse_type_with_opts(TypeOpts::default().allow_optional());
531 parser.skip_trivia();
532 root.complete(&mut parser, ROOT);
533 let parse: Parse = parser.finish(vec![]);
534 let output = format!("{:#?}", parse.syntax());
535 expect.assert_eq(&output);
536 }
537
538 #[test]
543 fn parse_type_bool() {
544 check_type("bool", expect![[r#"
545 ROOT@0..4
546 TYPE_PRIMITIVE@0..4
547 KW_BOOL@0..4 "bool"
548 "#]]);
549 }
550
551 #[test]
552 fn parse_type_field() {
553 check_type("field", expect![[r#"
554 ROOT@0..5
555 TYPE_PRIMITIVE@0..5
556 KW_FIELD@0..5 "field"
557 "#]]);
558 }
559
560 #[test]
561 fn parse_type_group() {
562 check_type("group", expect![[r#"
563 ROOT@0..5
564 TYPE_PRIMITIVE@0..5
565 KW_GROUP@0..5 "group"
566 "#]]);
567 }
568
569 #[test]
570 fn parse_type_address() {
571 check_type("address", expect![[r#"
572 ROOT@0..7
573 TYPE_PRIMITIVE@0..7
574 KW_ADDRESS@0..7 "address"
575 "#]]);
576 }
577
578 #[test]
579 fn parse_type_scalar() {
580 check_type("scalar", expect![[r#"
581 ROOT@0..6
582 TYPE_PRIMITIVE@0..6
583 KW_SCALAR@0..6 "scalar"
584 "#]]);
585 }
586
587 #[test]
588 fn parse_type_signature() {
589 check_type("signature", expect![[r#"
590 ROOT@0..9
591 TYPE_PRIMITIVE@0..9
592 KW_SIGNATURE@0..9 "signature"
593 "#]]);
594 }
595
596 #[test]
597 fn parse_type_string() {
598 check_type("string", expect![[r#"
599 ROOT@0..6
600 TYPE_PRIMITIVE@0..6
601 KW_STRING@0..6 "string"
602 "#]]);
603 }
604
605 #[test]
606 fn parse_type_identifier() {
607 check_type("identifier", expect![[r#"
608 ROOT@0..10
609 TYPE_PRIMITIVE@0..10
610 KW_IDENTIFIER@0..10 "identifier"
611 "#]]);
612 }
613
614 #[test]
615 fn parse_type_u32() {
616 check_type("u32", expect![[r#"
617 ROOT@0..3
618 TYPE_PRIMITIVE@0..3
619 KW_U32@0..3 "u32"
620 "#]]);
621 }
622
623 #[test]
624 fn parse_type_i128() {
625 check_type("i128", expect![[r#"
626 ROOT@0..4
627 TYPE_PRIMITIVE@0..4
628 KW_I128@0..4 "i128"
629 "#]]);
630 }
631
632 #[test]
637 fn parse_type_unit() {
638 check_type("()", expect![[r#"
639 ROOT@0..2
640 TYPE_TUPLE@0..2
641 L_PAREN@0..1 "("
642 R_PAREN@1..2 ")"
643 "#]]);
644 }
645
646 #[test]
647 fn parse_type_tuple_single() {
648 check_type("(u32)", expect![[r#"
649 ROOT@0..5
650 TYPE_TUPLE@0..5
651 L_PAREN@0..1 "("
652 TYPE_PRIMITIVE@1..4
653 KW_U32@1..4 "u32"
654 R_PAREN@4..5 ")"
655 "#]]);
656 }
657
658 #[test]
659 fn parse_type_tuple_pair() {
660 check_type("(u32, field)", expect![[r#"
661 ROOT@0..12
662 TYPE_TUPLE@0..12
663 L_PAREN@0..1 "("
664 TYPE_PRIMITIVE@1..4
665 KW_U32@1..4 "u32"
666 COMMA@4..5 ","
667 WHITESPACE@5..6 " "
668 TYPE_PRIMITIVE@6..11
669 KW_FIELD@6..11 "field"
670 R_PAREN@11..12 ")"
671 "#]]);
672 }
673
674 #[test]
675 fn parse_type_tuple_trailing_comma() {
676 check_type("(u32, field,)", expect![[r#"
677 ROOT@0..13
678 TYPE_TUPLE@0..13
679 L_PAREN@0..1 "("
680 TYPE_PRIMITIVE@1..4
681 KW_U32@1..4 "u32"
682 COMMA@4..5 ","
683 WHITESPACE@5..6 " "
684 TYPE_PRIMITIVE@6..11
685 KW_FIELD@6..11 "field"
686 COMMA@11..12 ","
687 R_PAREN@12..13 ")"
688 "#]]);
689 }
690
691 #[test]
696 fn parse_type_array_fixed() {
697 check_type("[u32; 10]", expect![[r#"
698 ROOT@0..9
699 TYPE_ARRAY@0..9
700 L_BRACKET@0..1 "["
701 TYPE_PRIMITIVE@1..4
702 KW_U32@1..4 "u32"
703 SEMICOLON@4..5 ";"
704 ARRAY_LENGTH@5..8
705 WHITESPACE@5..6 " "
706 LITERAL_INT@6..8
707 INTEGER@6..8 "10"
708 R_BRACKET@8..9 "]"
709 "#]]);
710 }
711
712 #[test]
713 fn parse_type_array_const_generic() {
714 check_type("[field; N]", expect![[r#"
715 ROOT@0..10
716 TYPE_ARRAY@0..10
717 L_BRACKET@0..1 "["
718 TYPE_PRIMITIVE@1..6
719 KW_FIELD@1..6 "field"
720 SEMICOLON@6..7 ";"
721 ARRAY_LENGTH@7..9
722 WHITESPACE@7..8 " "
723 PATH_EXPR@8..9
724 IDENT@8..9 "N"
725 R_BRACKET@9..10 "]"
726 "#]]);
727 }
728
729 #[test]
730 fn parse_type_vector() {
731 check_type("[u8]", expect![[r#"
732 ROOT@0..4
733 TYPE_VECTOR@0..4
734 L_BRACKET@0..1 "["
735 TYPE_PRIMITIVE@1..3
736 KW_U8@1..3 "u8"
737 R_BRACKET@3..4 "]"
738 "#]]);
739 }
740
741 #[test]
742 fn parse_type_nested_array() {
743 check_type("[[u32; 3]; 2]", expect![[r#"
744 ROOT@0..13
745 TYPE_ARRAY@0..13
746 L_BRACKET@0..1 "["
747 TYPE_ARRAY@1..9
748 L_BRACKET@1..2 "["
749 TYPE_PRIMITIVE@2..5
750 KW_U32@2..5 "u32"
751 SEMICOLON@5..6 ";"
752 ARRAY_LENGTH@6..8
753 WHITESPACE@6..7 " "
754 LITERAL_INT@7..8
755 INTEGER@7..8 "3"
756 R_BRACKET@8..9 "]"
757 SEMICOLON@9..10 ";"
758 ARRAY_LENGTH@10..12
759 WHITESPACE@10..11 " "
760 LITERAL_INT@11..12
761 INTEGER@11..12 "2"
762 R_BRACKET@12..13 "]"
763 "#]]);
764 }
765
766 #[test]
771 fn parse_type_optional() {
772 check_type_optional("u32?", expect![[r#"
773 ROOT@0..4
774 TYPE_OPTIONAL@0..4
775 TYPE_PRIMITIVE@0..3
776 KW_U32@0..3 "u32"
777 QUESTION@3..4 "?"
778 "#]]);
779 }
780
781 #[test]
782 fn parse_type_optional_named() {
783 check_type_optional("Token?", expect![[r#"
784 ROOT@0..6
785 TYPE_OPTIONAL@0..6
786 TYPE_PATH@0..5
787 IDENT@0..5 "Token"
788 QUESTION@5..6 "?"
789 "#]]);
790 }
791
792 #[test]
797 fn parse_type_named_simple() {
798 check_type("Token", expect![[r#"
799 ROOT@0..5
800 TYPE_PATH@0..5
801 IDENT@0..5 "Token"
802 "#]]);
803 }
804
805 #[test]
806 fn parse_type_named_path() {
807 check_type("Foo::Bar", expect![[r#"
808 ROOT@0..8
809 TYPE_PATH@0..8
810 IDENT@0..3 "Foo"
811 COLON_COLON@3..5 "::"
812 IDENT@5..8 "Bar"
813 "#]]);
814 }
815
816 #[test]
817 fn parse_type_named_const_generic_bracket() {
818 check_type("Poseidon::[N]", expect![[r#"
819 ROOT@0..13
820 TYPE_PATH@0..13
821 IDENT@0..8 "Poseidon"
822 COLON_COLON@8..10 "::"
823 CONST_ARG_LIST@10..13
824 L_BRACKET@10..11 "["
825 PATH_EXPR@11..12
826 IDENT@11..12 "N"
827 R_BRACKET@12..13 "]"
828 "#]]);
829 }
830
831 #[test]
832 fn parse_type_named_const_generic_angle() {
833 check_type("Poseidon::<4>", expect![[r#"
834 ROOT@0..13
835 TYPE_PATH@0..13
836 IDENT@0..8 "Poseidon"
837 COLON_COLON@8..10 "::"
838 CONST_ARG_LIST@10..13
839 LT@10..11 "<"
840 INTEGER@11..12 "4"
841 GT@12..13 ">"
842 "#]]);
843 }
844
845 #[test]
846 fn parse_type_locator() {
847 check_type("credits.aleo::Token", expect![[r#"
848 ROOT@0..19
849 TYPE_LOCATOR@0..19
850 IDENT@0..7 "credits"
851 DOT@7..8 "."
852 KW_ALEO@8..12 "aleo"
853 COLON_COLON@12..14 "::"
854 IDENT@14..19 "Token"
855 "#]]);
856 }
857
858 #[test]
859 fn parse_type_program_id_without_type() {
860 check_type("credits.aleo", expect![[r#"
862 ROOT@0..12
863 TYPE_LOCATOR@0..12
864 IDENT@0..7 "credits"
865 DOT@7..8 "."
866 KW_ALEO@8..12 "aleo"
867 "#]]);
868 }
869
870 #[test]
875 fn parse_type_final_simple() {
876 check_type("Final", expect![[r#"
877 ROOT@0..5
878 TYPE_FINAL@0..5
879 KW_FINAL_UPPER@0..5 "Final"
880 "#]]);
881 }
882
883 #[test]
884 fn parse_type_final_explicit() {
885 check_type("Final<Fn(u32) -> field>", expect![[r#"
886 ROOT@0..23
887 TYPE_FINAL@0..23
888 KW_FINAL_UPPER@0..5 "Final"
889 LT@5..6 "<"
890 KW_FN_UPPER@6..8 "Fn"
891 L_PAREN@8..9 "("
892 TYPE_PRIMITIVE@9..12
893 KW_U32@9..12 "u32"
894 R_PAREN@12..13 ")"
895 WHITESPACE@13..14 " "
896 ARROW@14..16 "->"
897 WHITESPACE@16..17 " "
898 TYPE_PRIMITIVE@17..22
899 KW_FIELD@17..22 "field"
900 GT@22..23 ">"
901 "#]]);
902 }
903
904 #[test]
905 fn parse_type_final_no_params() {
906 check_type("Final<Fn() -> ()>", expect![[r#"
907 ROOT@0..17
908 TYPE_FINAL@0..17
909 KW_FINAL_UPPER@0..5 "Final"
910 LT@5..6 "<"
911 KW_FN_UPPER@6..8 "Fn"
912 L_PAREN@8..9 "("
913 R_PAREN@9..10 ")"
914 WHITESPACE@10..11 " "
915 ARROW@11..13 "->"
916 WHITESPACE@13..14 " "
917 TYPE_TUPLE@14..16
918 L_PAREN@14..15 "("
919 R_PAREN@15..16 ")"
920 GT@16..17 ">"
921 "#]]);
922 }
923
924 #[test]
929 fn parse_type_mapping() {
930 check_type("mapping address => u64", expect![[r#"
931 ROOT@0..22
932 TYPE_MAPPING@0..22
933 KW_MAPPING@0..7 "mapping"
934 WHITESPACE@7..8 " "
935 TYPE_PRIMITIVE@8..15
936 KW_ADDRESS@8..15 "address"
937 WHITESPACE@15..16 " "
938 FAT_ARROW@16..18 "=>"
939 WHITESPACE@18..19 " "
940 TYPE_PRIMITIVE@19..22
941 KW_U64@19..22 "u64"
942 "#]]);
943 }
944
945 fn check_type_no_errors(input: &str) {
950 let (tokens, _) = lex(input);
951 let mut parser = Parser::new(input, &tokens);
952 let root = parser.start();
953 parser.parse_type();
954 parser.skip_trivia();
955 root.complete(&mut parser, ROOT);
956 let parse: Parse = parser.finish(vec![]);
957 if !parse.errors().is_empty() {
958 for err in parse.errors() {
959 eprintln!("error at {:?}: {}", err.range, err.message);
960 }
961 eprintln!("tree:\n{:#?}", parse.syntax());
962 panic!("type parse had {} error(s)", parse.errors().len());
963 }
964 }
965
966 #[test]
967 fn parse_type_const_generic_expr_simple() {
968 check_type_no_errors("Foo::[3]");
970 }
971
972 #[test]
973 fn parse_type_const_generic_expr_add() {
974 check_type_no_errors("Foo::[N + 1]");
976 }
977
978 #[test]
979 fn parse_type_const_generic_expr_mul() {
980 check_type_no_errors("Foo::[2 * N]");
981 }
982
983 #[test]
984 fn parse_type_const_generic_multi_args() {
985 check_type_no_errors("Matrix::[M, K, N]");
986 }
987
988 #[test]
989 fn parse_type_const_generic_type_arg() {
990 check_type_no_errors("Deserialize::[u32]");
992 }
993
994 #[test]
995 fn parse_type_const_generic_array_type_arg() {
996 check_type_no_errors("Deserialize::[[u8; 4]]");
998 }
999
1000 #[test]
1001 fn parse_type_locator_const_generic() {
1002 check_type_no_errors("child.aleo::Bar::[4]");
1004 }
1005
1006 #[test]
1011 fn parse_type_tuple_nested() {
1012 check_type("((u32, u64), bool)", expect![[r#"
1013 ROOT@0..18
1014 TYPE_TUPLE@0..18
1015 L_PAREN@0..1 "("
1016 TYPE_TUPLE@1..11
1017 L_PAREN@1..2 "("
1018 TYPE_PRIMITIVE@2..5
1019 KW_U32@2..5 "u32"
1020 COMMA@5..6 ","
1021 WHITESPACE@6..7 " "
1022 TYPE_PRIMITIVE@7..10
1023 KW_U64@7..10 "u64"
1024 R_PAREN@10..11 ")"
1025 COMMA@11..12 ","
1026 WHITESPACE@12..13 " "
1027 TYPE_PRIMITIVE@13..17
1028 KW_BOOL@13..17 "bool"
1029 R_PAREN@17..18 ")"
1030 "#]]);
1031 }
1032
1033 #[test]
1038 fn parse_type_optional_array() {
1039 check_type_optional("[u32; 3]?", expect![[r#"
1040 ROOT@0..9
1041 TYPE_OPTIONAL@0..9
1042 TYPE_ARRAY@0..8
1043 L_BRACKET@0..1 "["
1044 TYPE_PRIMITIVE@1..4
1045 KW_U32@1..4 "u32"
1046 SEMICOLON@4..5 ";"
1047 ARRAY_LENGTH@5..7
1048 WHITESPACE@5..6 " "
1049 LITERAL_INT@6..7
1050 INTEGER@6..7 "3"
1051 R_BRACKET@7..8 "]"
1052 QUESTION@8..9 "?"
1053 "#]]);
1054 }
1055
1056 #[test]
1057 fn parse_type_optional_tuple() {
1058 check_type_optional("(u32, u64)?", expect![[r#"
1059 ROOT@0..11
1060 TYPE_OPTIONAL@0..11
1061 TYPE_TUPLE@0..10
1062 L_PAREN@0..1 "("
1063 TYPE_PRIMITIVE@1..4
1064 KW_U32@1..4 "u32"
1065 COMMA@4..5 ","
1066 WHITESPACE@5..6 " "
1067 TYPE_PRIMITIVE@6..9
1068 KW_U64@6..9 "u64"
1069 R_PAREN@9..10 ")"
1070 QUESTION@10..11 "?"
1071 "#]]);
1072 }
1073
1074 #[test]
1079 fn parse_type_final_multi_param() {
1080 check_type("Final<Fn(u32, field, group) -> (u32, u64)>", expect![[r#"
1081 ROOT@0..42
1082 TYPE_FINAL@0..42
1083 KW_FINAL_UPPER@0..5 "Final"
1084 LT@5..6 "<"
1085 KW_FN_UPPER@6..8 "Fn"
1086 L_PAREN@8..9 "("
1087 TYPE_PRIMITIVE@9..12
1088 KW_U32@9..12 "u32"
1089 COMMA@12..13 ","
1090 WHITESPACE@13..14 " "
1091 TYPE_PRIMITIVE@14..19
1092 KW_FIELD@14..19 "field"
1093 COMMA@19..20 ","
1094 WHITESPACE@20..21 " "
1095 TYPE_PRIMITIVE@21..26
1096 KW_GROUP@21..26 "group"
1097 R_PAREN@26..27 ")"
1098 WHITESPACE@27..28 " "
1099 ARROW@28..30 "->"
1100 WHITESPACE@30..31 " "
1101 TYPE_TUPLE@31..41
1102 L_PAREN@31..32 "("
1103 TYPE_PRIMITIVE@32..35
1104 KW_U32@32..35 "u32"
1105 COMMA@35..36 ","
1106 WHITESPACE@36..37 " "
1107 TYPE_PRIMITIVE@37..40
1108 KW_U64@37..40 "u64"
1109 R_PAREN@40..41 ")"
1110 GT@41..42 ">"
1111 "#]]);
1112 }
1113
1114 #[test]
1119 fn parse_type_const_generic_expr_sub() {
1120 check_type("Foo::[N - 1]", expect![[r#"
1121 ROOT@0..12
1122 TYPE_PATH@0..12
1123 IDENT@0..3 "Foo"
1124 COLON_COLON@3..5 "::"
1125 CONST_ARG_LIST@5..12
1126 L_BRACKET@5..6 "["
1127 BINARY_EXPR@6..11
1128 PATH_EXPR@6..8
1129 IDENT@6..7 "N"
1130 WHITESPACE@7..8 " "
1131 MINUS@8..9 "-"
1132 WHITESPACE@9..10 " "
1133 LITERAL_INT@10..11
1134 INTEGER@10..11 "1"
1135 R_BRACKET@11..12 "]"
1136 "#]]);
1137 }
1138}