diff --git a/grammar.ron b/grammar.ron index b43b58f02a..bc7dd7c553 100644 --- a/grammar.ron +++ b/grammar.ron @@ -106,6 +106,8 @@ Grammar( "NEVER_TYPE", "PATH_TYPE", "POINTER_TYPE", + "ARRAY_TYPE", + "SLICE_TYPE", "EXTERN_BLOCK", "ENUM_VARIANT", diff --git a/src/parser/grammar/types.rs b/src/parser/grammar/types.rs index ceadf5f96a..4eb333b54e 100644 --- a/src/parser/grammar/types.rs +++ b/src/parser/grammar/types.rs @@ -5,6 +5,7 @@ pub(super) fn type_(p: &mut Parser) { L_PAREN => paren_or_tuple_type(p), EXCL => never_type(p), STAR => pointer_type(p), + L_BRACK => array_or_slice_type(p), IDENT => path_type(p), _ => { p.error("expected type"); @@ -82,6 +83,38 @@ fn pointer_type(p: &mut Parser) { m.complete(p, POINTER_TYPE); } +fn array_or_slice_type(p: &mut Parser) { + assert!(p.at(L_BRACK)); + let m = p.start(); + p.bump(); + + type_(p); + let kind = match p.current() { + // test slice_type + // type T = [()]; + R_BRACK => { + p.bump(); + SLICE_TYPE + }, + + // test array_type + // type T = [(); 92]; + SEMI => { + p.bump(); + expressions::expr(p); + p.expect(R_BRACK); + ARRAY_TYPE + } + // test array_type_missing_semi + // type T = [() 92]; + _ => { + p.error("expected `;` or `]`"); + SLICE_TYPE + } + }; + m.complete(p, kind); +} + fn path_type(p: &mut Parser) { assert!(p.at(IDENT)); let m = p.start(); diff --git a/src/syntax_kinds.rs b/src/syntax_kinds.rs index 181dcc63b8..54200f2d1f 100644 --- a/src/syntax_kinds.rs +++ b/src/syntax_kinds.rs @@ -104,6 +104,8 @@ pub enum SyntaxKind { NEVER_TYPE, PATH_TYPE, POINTER_TYPE, + ARRAY_TYPE, + SLICE_TYPE, EXTERN_BLOCK, ENUM_VARIANT, NAMED_FIELD, @@ -234,6 +236,8 @@ impl SyntaxKind { NEVER_TYPE => &SyntaxInfo { name: "NEVER_TYPE" }, PATH_TYPE => &SyntaxInfo { name: "PATH_TYPE" }, POINTER_TYPE => &SyntaxInfo { name: "POINTER_TYPE" }, + ARRAY_TYPE => &SyntaxInfo { name: "ARRAY_TYPE" }, + SLICE_TYPE => &SyntaxInfo { name: "SLICE_TYPE" }, EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" }, ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, diff --git a/tests/data/parser/inline/0023_array_type_missing_semi.rs b/tests/data/parser/inline/0023_array_type_missing_semi.rs new file mode 100644 index 0000000000..a948514432 --- /dev/null +++ b/tests/data/parser/inline/0023_array_type_missing_semi.rs @@ -0,0 +1 @@ +type T = [() 92]; diff --git a/tests/data/parser/inline/0023_array_type_missing_semi.txt b/tests/data/parser/inline/0023_array_type_missing_semi.txt new file mode 100644 index 0000000000..bb30a2a2a7 --- /dev/null +++ b/tests/data/parser/inline/0023_array_type_missing_semi.txt @@ -0,0 +1,28 @@ +FILE@[0; 18) + TYPE_ITEM@[0; 13) + TYPE_KW@[0; 4) + NAME@[4; 7) + WHITESPACE@[4; 5) + IDENT@[5; 6) "T" + WHITESPACE@[6; 7) + EQ@[7; 8) + SLICE_TYPE@[8; 13) + WHITESPACE@[8; 9) + L_BRACK@[9; 10) + TUPLE_TYPE@[10; 13) + L_PAREN@[10; 11) + R_PAREN@[11; 12) + WHITESPACE@[12; 13) + err: `expected `;` or `]`` + err: `expected SEMI` + ERROR@[13; 15) + err: `expected item` + INT_NUMBER@[13; 15) + ERROR@[15; 16) + err: `expected item` + R_BRACK@[15; 16) + ERROR@[16; 18) + err: `expected item, found `;` +consider removing this semicolon` + SEMI@[16; 17) + WHITESPACE@[17; 18) diff --git a/tests/data/parser/inline/0024_array_type.rs b/tests/data/parser/inline/0024_array_type.rs new file mode 100644 index 0000000000..27eb22f223 --- /dev/null +++ b/tests/data/parser/inline/0024_array_type.rs @@ -0,0 +1 @@ +type T = [(); 92]; diff --git a/tests/data/parser/inline/0024_array_type.txt b/tests/data/parser/inline/0024_array_type.txt new file mode 100644 index 0000000000..970734a198 --- /dev/null +++ b/tests/data/parser/inline/0024_array_type.txt @@ -0,0 +1,21 @@ +FILE@[0; 19) + TYPE_ITEM@[0; 19) + TYPE_KW@[0; 4) + NAME@[4; 7) + WHITESPACE@[4; 5) + IDENT@[5; 6) "T" + WHITESPACE@[6; 7) + EQ@[7; 8) + ARRAY_TYPE@[8; 17) + WHITESPACE@[8; 9) + L_BRACK@[9; 10) + TUPLE_TYPE@[10; 12) + L_PAREN@[10; 11) + R_PAREN@[11; 12) + SEMI@[12; 13) + LITERAL@[13; 16) + WHITESPACE@[13; 14) + INT_NUMBER@[14; 16) + R_BRACK@[16; 17) + SEMI@[17; 18) + WHITESPACE@[18; 19) diff --git a/tests/data/parser/inline/0025_slice_type.rs b/tests/data/parser/inline/0025_slice_type.rs new file mode 100644 index 0000000000..4da1af8270 --- /dev/null +++ b/tests/data/parser/inline/0025_slice_type.rs @@ -0,0 +1 @@ +type T = [()]; diff --git a/tests/data/parser/inline/0025_slice_type.txt b/tests/data/parser/inline/0025_slice_type.txt new file mode 100644 index 0000000000..22938e5e1d --- /dev/null +++ b/tests/data/parser/inline/0025_slice_type.txt @@ -0,0 +1,17 @@ +FILE@[0; 15) + TYPE_ITEM@[0; 15) + TYPE_KW@[0; 4) + NAME@[4; 7) + WHITESPACE@[4; 5) + IDENT@[5; 6) "T" + WHITESPACE@[6; 7) + EQ@[7; 8) + SLICE_TYPE@[8; 13) + WHITESPACE@[8; 9) + L_BRACK@[9; 10) + TUPLE_TYPE@[10; 12) + L_PAREN@[10; 11) + R_PAREN@[11; 12) + R_BRACK@[12; 13) + SEMI@[13; 14) + WHITESPACE@[14; 15)