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 } else {
323 self.error("expected type name after ::");
324 }
325 }
326
327 if self.at(COLON_COLON) && self.nth(1) == L_BRACKET {
329 self.bump_any(); self.parse_const_generic_args_bracket();
331 }
332
333 return Some(m.complete(self, TYPE_LOCATOR));
334 }
335
336 while self.eat(COLON_COLON) {
338 if self.at(L_BRACKET) {
339 self.parse_const_generic_args_bracket();
341 break;
342 } else if self.at(LT) {
343 self.parse_const_generic_args_angle();
345 break;
346 } else if self.at(IDENT) {
347 self.bump_any();
348 } else {
349 self.error("expected identifier, [, or < after ::");
350 break;
351 }
352 }
353
354 Some(m.complete(self, TYPE_PATH))
355 }
356
357 pub fn parse_const_param_list(&mut self) {
362 let m = self.start();
363
364 if !self.eat(L_BRACKET) {
365 m.abandon(self);
366 return;
367 }
368
369 if !self.at(R_BRACKET) {
371 self.parse_const_param();
372 while self.eat(COMMA) {
373 if self.at(R_BRACKET) {
374 break;
375 }
376 self.parse_const_param();
377 }
378 }
379
380 self.expect(R_BRACKET);
381 m.complete(self, CONST_PARAM_LIST);
382 }
383
384 fn parse_const_param(&mut self) {
386 let m = self.start();
387 self.skip_trivia();
388
389 if self.at(IDENT) {
390 self.bump_any(); } else {
392 self.error("expected const parameter name");
393 }
394
395 self.expect(COLON);
396 self.parse_type();
397
398 m.complete(self, CONST_PARAM);
399 }
400
401 pub fn parse_const_generic_args_bracket(&mut self) {
406 let m = self.start();
407
408 if !self.eat(L_BRACKET) {
409 m.abandon(self);
410 return;
411 }
412
413 if !self.at(R_BRACKET) {
415 self.parse_const_generic_arg();
416 while self.eat(COMMA) {
417 if self.at(R_BRACKET) {
418 break;
419 }
420 self.erroring = false;
422 self.parse_const_generic_arg();
423 }
424 }
425
426 self.expect(R_BRACKET);
427 m.complete(self, CONST_ARG_LIST);
428 }
429
430 pub fn parse_const_generic_args_angle(&mut self) {
436 let m = self.start();
437
438 if !self.eat(LT) {
439 m.abandon(self);
440 return;
441 }
442
443 if self.at(IDENT) || self.at(INTEGER) {
445 self.bump_any();
446 }
447
448 while self.eat(COMMA) {
449 if self.at(GT) {
450 break;
451 }
452 if self.at(IDENT) || self.at(INTEGER) {
453 self.bump_any();
454 } else {
455 self.error("expected const generic argument");
456 break;
457 }
458 }
459
460 self.expect(GT);
461 m.complete(self, CONST_ARG_LIST);
462 }
463
464 fn parse_const_generic_arg(&mut self) {
472 self.skip_trivia();
473 if matches!(self.current(), KW_PUBLIC | KW_PRIVATE | KW_CONSTANT) {
474 let m = self.start();
476 self.bump_any(); self.parse_type();
478 m.complete(self, DYNAMIC_CALL_RETURN_TYPE);
479 } else if self.at_primitive_type() {
480 self.parse_type();
482 } else if self.at(L_BRACKET) && self.nth(1).is_type_keyword() {
483 self.parse_type();
485 } else if self.at(KW_FINAL_UPPER) {
486 self.parse_type();
488 } else if self.at(KW_DYN) {
489 self.parse_type();
491 } else if self.at(L_PAREN) && (self.nth(1) == R_PAREN || Self::PRIMITIVE_TYPE_KINDS.contains(&self.nth(1))) {
492 self.parse_type();
496 } else {
497 self.parse_expr();
499 }
500 }
501}
502
503#[cfg(test)]
504mod tests {
505 use super::*;
506 use crate::{lexer::lex, parser::Parse};
507 use expect_test::{Expect, expect};
508
509 fn check_type(input: &str, expect: Expect) {
510 let (tokens, _) = lex(input);
511 let mut parser = Parser::new(input, &tokens);
512 let root = parser.start();
513 parser.parse_type();
514 parser.skip_trivia();
515 root.complete(&mut parser, ROOT);
516 let parse: Parse = parser.finish(vec![]);
517 let output = format!("{:#?}", parse.syntax());
518 expect.assert_eq(&output);
519 }
520
521 fn check_type_optional(input: &str, expect: Expect) {
522 let (tokens, _) = lex(input);
523 let mut parser = Parser::new(input, &tokens);
524 let root = parser.start();
525 parser.parse_type_with_opts(TypeOpts::default().allow_optional());
526 parser.skip_trivia();
527 root.complete(&mut parser, ROOT);
528 let parse: Parse = parser.finish(vec![]);
529 let output = format!("{:#?}", parse.syntax());
530 expect.assert_eq(&output);
531 }
532
533 #[test]
538 fn parse_type_bool() {
539 check_type("bool", expect![[r#"
540 ROOT@0..4
541 TYPE_PRIMITIVE@0..4
542 KW_BOOL@0..4 "bool"
543 "#]]);
544 }
545
546 #[test]
547 fn parse_type_field() {
548 check_type("field", expect![[r#"
549 ROOT@0..5
550 TYPE_PRIMITIVE@0..5
551 KW_FIELD@0..5 "field"
552 "#]]);
553 }
554
555 #[test]
556 fn parse_type_group() {
557 check_type("group", expect![[r#"
558 ROOT@0..5
559 TYPE_PRIMITIVE@0..5
560 KW_GROUP@0..5 "group"
561 "#]]);
562 }
563
564 #[test]
565 fn parse_type_address() {
566 check_type("address", expect![[r#"
567 ROOT@0..7
568 TYPE_PRIMITIVE@0..7
569 KW_ADDRESS@0..7 "address"
570 "#]]);
571 }
572
573 #[test]
574 fn parse_type_scalar() {
575 check_type("scalar", expect![[r#"
576 ROOT@0..6
577 TYPE_PRIMITIVE@0..6
578 KW_SCALAR@0..6 "scalar"
579 "#]]);
580 }
581
582 #[test]
583 fn parse_type_signature() {
584 check_type("signature", expect![[r#"
585 ROOT@0..9
586 TYPE_PRIMITIVE@0..9
587 KW_SIGNATURE@0..9 "signature"
588 "#]]);
589 }
590
591 #[test]
592 fn parse_type_string() {
593 check_type("string", expect![[r#"
594 ROOT@0..6
595 TYPE_PRIMITIVE@0..6
596 KW_STRING@0..6 "string"
597 "#]]);
598 }
599
600 #[test]
601 fn parse_type_identifier() {
602 check_type("identifier", expect![[r#"
603 ROOT@0..10
604 TYPE_PRIMITIVE@0..10
605 KW_IDENTIFIER@0..10 "identifier"
606 "#]]);
607 }
608
609 #[test]
610 fn parse_type_u32() {
611 check_type("u32", expect![[r#"
612 ROOT@0..3
613 TYPE_PRIMITIVE@0..3
614 KW_U32@0..3 "u32"
615 "#]]);
616 }
617
618 #[test]
619 fn parse_type_i128() {
620 check_type("i128", expect![[r#"
621 ROOT@0..4
622 TYPE_PRIMITIVE@0..4
623 KW_I128@0..4 "i128"
624 "#]]);
625 }
626
627 #[test]
632 fn parse_type_unit() {
633 check_type("()", expect![[r#"
634 ROOT@0..2
635 TYPE_TUPLE@0..2
636 L_PAREN@0..1 "("
637 R_PAREN@1..2 ")"
638 "#]]);
639 }
640
641 #[test]
642 fn parse_type_tuple_single() {
643 check_type("(u32)", expect![[r#"
644 ROOT@0..5
645 TYPE_TUPLE@0..5
646 L_PAREN@0..1 "("
647 TYPE_PRIMITIVE@1..4
648 KW_U32@1..4 "u32"
649 R_PAREN@4..5 ")"
650 "#]]);
651 }
652
653 #[test]
654 fn parse_type_tuple_pair() {
655 check_type("(u32, field)", expect![[r#"
656 ROOT@0..12
657 TYPE_TUPLE@0..12
658 L_PAREN@0..1 "("
659 TYPE_PRIMITIVE@1..4
660 KW_U32@1..4 "u32"
661 COMMA@4..5 ","
662 WHITESPACE@5..6 " "
663 TYPE_PRIMITIVE@6..11
664 KW_FIELD@6..11 "field"
665 R_PAREN@11..12 ")"
666 "#]]);
667 }
668
669 #[test]
670 fn parse_type_tuple_trailing_comma() {
671 check_type("(u32, field,)", expect![[r#"
672 ROOT@0..13
673 TYPE_TUPLE@0..13
674 L_PAREN@0..1 "("
675 TYPE_PRIMITIVE@1..4
676 KW_U32@1..4 "u32"
677 COMMA@4..5 ","
678 WHITESPACE@5..6 " "
679 TYPE_PRIMITIVE@6..11
680 KW_FIELD@6..11 "field"
681 COMMA@11..12 ","
682 R_PAREN@12..13 ")"
683 "#]]);
684 }
685
686 #[test]
691 fn parse_type_array_fixed() {
692 check_type("[u32; 10]", expect![[r#"
693 ROOT@0..9
694 TYPE_ARRAY@0..9
695 L_BRACKET@0..1 "["
696 TYPE_PRIMITIVE@1..4
697 KW_U32@1..4 "u32"
698 SEMICOLON@4..5 ";"
699 ARRAY_LENGTH@5..8
700 WHITESPACE@5..6 " "
701 LITERAL_INT@6..8
702 INTEGER@6..8 "10"
703 R_BRACKET@8..9 "]"
704 "#]]);
705 }
706
707 #[test]
708 fn parse_type_array_const_generic() {
709 check_type("[field; N]", expect![[r#"
710 ROOT@0..10
711 TYPE_ARRAY@0..10
712 L_BRACKET@0..1 "["
713 TYPE_PRIMITIVE@1..6
714 KW_FIELD@1..6 "field"
715 SEMICOLON@6..7 ";"
716 ARRAY_LENGTH@7..9
717 WHITESPACE@7..8 " "
718 PATH_EXPR@8..9
719 IDENT@8..9 "N"
720 R_BRACKET@9..10 "]"
721 "#]]);
722 }
723
724 #[test]
725 fn parse_type_vector() {
726 check_type("[u8]", expect![[r#"
727 ROOT@0..4
728 TYPE_VECTOR@0..4
729 L_BRACKET@0..1 "["
730 TYPE_PRIMITIVE@1..3
731 KW_U8@1..3 "u8"
732 R_BRACKET@3..4 "]"
733 "#]]);
734 }
735
736 #[test]
737 fn parse_type_nested_array() {
738 check_type("[[u32; 3]; 2]", expect![[r#"
739 ROOT@0..13
740 TYPE_ARRAY@0..13
741 L_BRACKET@0..1 "["
742 TYPE_ARRAY@1..9
743 L_BRACKET@1..2 "["
744 TYPE_PRIMITIVE@2..5
745 KW_U32@2..5 "u32"
746 SEMICOLON@5..6 ";"
747 ARRAY_LENGTH@6..8
748 WHITESPACE@6..7 " "
749 LITERAL_INT@7..8
750 INTEGER@7..8 "3"
751 R_BRACKET@8..9 "]"
752 SEMICOLON@9..10 ";"
753 ARRAY_LENGTH@10..12
754 WHITESPACE@10..11 " "
755 LITERAL_INT@11..12
756 INTEGER@11..12 "2"
757 R_BRACKET@12..13 "]"
758 "#]]);
759 }
760
761 #[test]
766 fn parse_type_optional() {
767 check_type_optional("u32?", expect![[r#"
768 ROOT@0..4
769 TYPE_OPTIONAL@0..4
770 TYPE_PRIMITIVE@0..3
771 KW_U32@0..3 "u32"
772 QUESTION@3..4 "?"
773 "#]]);
774 }
775
776 #[test]
777 fn parse_type_optional_named() {
778 check_type_optional("Token?", expect![[r#"
779 ROOT@0..6
780 TYPE_OPTIONAL@0..6
781 TYPE_PATH@0..5
782 IDENT@0..5 "Token"
783 QUESTION@5..6 "?"
784 "#]]);
785 }
786
787 #[test]
792 fn parse_type_named_simple() {
793 check_type("Token", expect![[r#"
794 ROOT@0..5
795 TYPE_PATH@0..5
796 IDENT@0..5 "Token"
797 "#]]);
798 }
799
800 #[test]
801 fn parse_type_named_path() {
802 check_type("Foo::Bar", expect![[r#"
803 ROOT@0..8
804 TYPE_PATH@0..8
805 IDENT@0..3 "Foo"
806 COLON_COLON@3..5 "::"
807 IDENT@5..8 "Bar"
808 "#]]);
809 }
810
811 #[test]
812 fn parse_type_named_const_generic_bracket() {
813 check_type("Poseidon::[N]", expect![[r#"
814 ROOT@0..13
815 TYPE_PATH@0..13
816 IDENT@0..8 "Poseidon"
817 COLON_COLON@8..10 "::"
818 CONST_ARG_LIST@10..13
819 L_BRACKET@10..11 "["
820 PATH_EXPR@11..12
821 IDENT@11..12 "N"
822 R_BRACKET@12..13 "]"
823 "#]]);
824 }
825
826 #[test]
827 fn parse_type_named_const_generic_angle() {
828 check_type("Poseidon::<4>", expect![[r#"
829 ROOT@0..13
830 TYPE_PATH@0..13
831 IDENT@0..8 "Poseidon"
832 COLON_COLON@8..10 "::"
833 CONST_ARG_LIST@10..13
834 LT@10..11 "<"
835 INTEGER@11..12 "4"
836 GT@12..13 ">"
837 "#]]);
838 }
839
840 #[test]
841 fn parse_type_locator() {
842 check_type("credits.aleo::Token", expect![[r#"
843 ROOT@0..19
844 TYPE_LOCATOR@0..19
845 IDENT@0..7 "credits"
846 DOT@7..8 "."
847 KW_ALEO@8..12 "aleo"
848 COLON_COLON@12..14 "::"
849 IDENT@14..19 "Token"
850 "#]]);
851 }
852
853 #[test]
854 fn parse_type_program_id_without_type() {
855 check_type("credits.aleo", expect![[r#"
857 ROOT@0..12
858 TYPE_LOCATOR@0..12
859 IDENT@0..7 "credits"
860 DOT@7..8 "."
861 KW_ALEO@8..12 "aleo"
862 "#]]);
863 }
864
865 #[test]
870 fn parse_type_final_simple() {
871 check_type("Final", expect![[r#"
872 ROOT@0..5
873 TYPE_FINAL@0..5
874 KW_FINAL_UPPER@0..5 "Final"
875 "#]]);
876 }
877
878 #[test]
879 fn parse_type_final_explicit() {
880 check_type("Final<Fn(u32) -> field>", expect![[r#"
881 ROOT@0..23
882 TYPE_FINAL@0..23
883 KW_FINAL_UPPER@0..5 "Final"
884 LT@5..6 "<"
885 KW_FN_UPPER@6..8 "Fn"
886 L_PAREN@8..9 "("
887 TYPE_PRIMITIVE@9..12
888 KW_U32@9..12 "u32"
889 R_PAREN@12..13 ")"
890 WHITESPACE@13..14 " "
891 ARROW@14..16 "->"
892 WHITESPACE@16..17 " "
893 TYPE_PRIMITIVE@17..22
894 KW_FIELD@17..22 "field"
895 GT@22..23 ">"
896 "#]]);
897 }
898
899 #[test]
900 fn parse_type_final_no_params() {
901 check_type("Final<Fn() -> ()>", expect![[r#"
902 ROOT@0..17
903 TYPE_FINAL@0..17
904 KW_FINAL_UPPER@0..5 "Final"
905 LT@5..6 "<"
906 KW_FN_UPPER@6..8 "Fn"
907 L_PAREN@8..9 "("
908 R_PAREN@9..10 ")"
909 WHITESPACE@10..11 " "
910 ARROW@11..13 "->"
911 WHITESPACE@13..14 " "
912 TYPE_TUPLE@14..16
913 L_PAREN@14..15 "("
914 R_PAREN@15..16 ")"
915 GT@16..17 ">"
916 "#]]);
917 }
918
919 #[test]
924 fn parse_type_mapping() {
925 check_type("mapping address => u64", expect![[r#"
926 ROOT@0..22
927 TYPE_MAPPING@0..22
928 KW_MAPPING@0..7 "mapping"
929 WHITESPACE@7..8 " "
930 TYPE_PRIMITIVE@8..15
931 KW_ADDRESS@8..15 "address"
932 WHITESPACE@15..16 " "
933 FAT_ARROW@16..18 "=>"
934 WHITESPACE@18..19 " "
935 TYPE_PRIMITIVE@19..22
936 KW_U64@19..22 "u64"
937 "#]]);
938 }
939
940 fn check_type_no_errors(input: &str) {
945 let (tokens, _) = lex(input);
946 let mut parser = Parser::new(input, &tokens);
947 let root = parser.start();
948 parser.parse_type();
949 parser.skip_trivia();
950 root.complete(&mut parser, ROOT);
951 let parse: Parse = parser.finish(vec![]);
952 if !parse.errors().is_empty() {
953 for err in parse.errors() {
954 eprintln!("error at {:?}: {}", err.range, err.message);
955 }
956 eprintln!("tree:\n{:#?}", parse.syntax());
957 panic!("type parse had {} error(s)", parse.errors().len());
958 }
959 }
960
961 #[test]
962 fn parse_type_const_generic_expr_simple() {
963 check_type_no_errors("Foo::[3]");
965 }
966
967 #[test]
968 fn parse_type_const_generic_expr_add() {
969 check_type_no_errors("Foo::[N + 1]");
971 }
972
973 #[test]
974 fn parse_type_const_generic_expr_mul() {
975 check_type_no_errors("Foo::[2 * N]");
976 }
977
978 #[test]
979 fn parse_type_const_generic_multi_args() {
980 check_type_no_errors("Matrix::[M, K, N]");
981 }
982
983 #[test]
984 fn parse_type_const_generic_type_arg() {
985 check_type_no_errors("Deserialize::[u32]");
987 }
988
989 #[test]
990 fn parse_type_const_generic_array_type_arg() {
991 check_type_no_errors("Deserialize::[[u8; 4]]");
993 }
994
995 #[test]
996 fn parse_type_locator_const_generic() {
997 check_type_no_errors("child.aleo::Bar::[4]");
999 }
1000
1001 #[test]
1006 fn parse_type_tuple_nested() {
1007 check_type("((u32, u64), bool)", expect![[r#"
1008 ROOT@0..18
1009 TYPE_TUPLE@0..18
1010 L_PAREN@0..1 "("
1011 TYPE_TUPLE@1..11
1012 L_PAREN@1..2 "("
1013 TYPE_PRIMITIVE@2..5
1014 KW_U32@2..5 "u32"
1015 COMMA@5..6 ","
1016 WHITESPACE@6..7 " "
1017 TYPE_PRIMITIVE@7..10
1018 KW_U64@7..10 "u64"
1019 R_PAREN@10..11 ")"
1020 COMMA@11..12 ","
1021 WHITESPACE@12..13 " "
1022 TYPE_PRIMITIVE@13..17
1023 KW_BOOL@13..17 "bool"
1024 R_PAREN@17..18 ")"
1025 "#]]);
1026 }
1027
1028 #[test]
1033 fn parse_type_optional_array() {
1034 check_type_optional("[u32; 3]?", expect![[r#"
1035 ROOT@0..9
1036 TYPE_OPTIONAL@0..9
1037 TYPE_ARRAY@0..8
1038 L_BRACKET@0..1 "["
1039 TYPE_PRIMITIVE@1..4
1040 KW_U32@1..4 "u32"
1041 SEMICOLON@4..5 ";"
1042 ARRAY_LENGTH@5..7
1043 WHITESPACE@5..6 " "
1044 LITERAL_INT@6..7
1045 INTEGER@6..7 "3"
1046 R_BRACKET@7..8 "]"
1047 QUESTION@8..9 "?"
1048 "#]]);
1049 }
1050
1051 #[test]
1052 fn parse_type_optional_tuple() {
1053 check_type_optional("(u32, u64)?", expect![[r#"
1054 ROOT@0..11
1055 TYPE_OPTIONAL@0..11
1056 TYPE_TUPLE@0..10
1057 L_PAREN@0..1 "("
1058 TYPE_PRIMITIVE@1..4
1059 KW_U32@1..4 "u32"
1060 COMMA@4..5 ","
1061 WHITESPACE@5..6 " "
1062 TYPE_PRIMITIVE@6..9
1063 KW_U64@6..9 "u64"
1064 R_PAREN@9..10 ")"
1065 QUESTION@10..11 "?"
1066 "#]]);
1067 }
1068
1069 #[test]
1074 fn parse_type_final_multi_param() {
1075 check_type("Final<Fn(u32, field, group) -> (u32, u64)>", expect![[r#"
1076 ROOT@0..42
1077 TYPE_FINAL@0..42
1078 KW_FINAL_UPPER@0..5 "Final"
1079 LT@5..6 "<"
1080 KW_FN_UPPER@6..8 "Fn"
1081 L_PAREN@8..9 "("
1082 TYPE_PRIMITIVE@9..12
1083 KW_U32@9..12 "u32"
1084 COMMA@12..13 ","
1085 WHITESPACE@13..14 " "
1086 TYPE_PRIMITIVE@14..19
1087 KW_FIELD@14..19 "field"
1088 COMMA@19..20 ","
1089 WHITESPACE@20..21 " "
1090 TYPE_PRIMITIVE@21..26
1091 KW_GROUP@21..26 "group"
1092 R_PAREN@26..27 ")"
1093 WHITESPACE@27..28 " "
1094 ARROW@28..30 "->"
1095 WHITESPACE@30..31 " "
1096 TYPE_TUPLE@31..41
1097 L_PAREN@31..32 "("
1098 TYPE_PRIMITIVE@32..35
1099 KW_U32@32..35 "u32"
1100 COMMA@35..36 ","
1101 WHITESPACE@36..37 " "
1102 TYPE_PRIMITIVE@37..40
1103 KW_U64@37..40 "u64"
1104 R_PAREN@40..41 ")"
1105 GT@41..42 ">"
1106 "#]]);
1107 }
1108
1109 #[test]
1114 fn parse_type_const_generic_expr_sub() {
1115 check_type("Foo::[N - 1]", expect![[r#"
1116 ROOT@0..12
1117 TYPE_PATH@0..12
1118 IDENT@0..3 "Foo"
1119 COLON_COLON@3..5 "::"
1120 CONST_ARG_LIST@5..12
1121 L_BRACKET@5..6 "["
1122 BINARY_EXPR@6..11
1123 PATH_EXPR@6..8
1124 IDENT@6..7 "N"
1125 WHITESPACE@7..8 " "
1126 MINUS@8..9 "-"
1127 WHITESPACE@9..10 " "
1128 LITERAL_INT@10..11
1129 INTEGER@10..11 "1"
1130 R_BRACKET@11..12 "]"
1131 "#]]);
1132 }
1133}