aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/grammar.ron3
-rw-r--r--src/grammar/patterns.rs92
-rw-r--r--src/syntax_kinds/generated.rs6
-rw-r--r--tests/data/parser/inline/0071_tuple_pat_fields.rs6
-rw-r--r--tests/data/parser/inline/0071_tuple_pat_fields.txt103
-rw-r--r--tests/data/parser/inline/0072_path_part.rs6
-rw-r--r--tests/data/parser/inline/0072_path_part.txt94
-rw-r--r--tests/data/parser/inline/0073_struct_pat_fields.rs6
-rw-r--r--tests/data/parser/inline/0073_struct_pat_fields.txt122
9 files changed, 434 insertions, 4 deletions
diff --git a/src/grammar.ron b/src/grammar.ron
index 0239a3c1d..655ed2e40 100644
--- a/src/grammar.ron
+++ b/src/grammar.ron
@@ -126,6 +126,9 @@ Grammar(
126 "REF_PAT", 126 "REF_PAT",
127 "BIND_PAT", 127 "BIND_PAT",
128 "PLACEHOLDER_PAT", 128 "PLACEHOLDER_PAT",
129 "PATH_PAT",
130 "STRUCT_PAT",
131 "TUPLE_PAT",
129 132
130 "TUPLE_EXPR", 133 "TUPLE_EXPR",
131 "PATH_EXPR", 134 "PATH_EXPR",
diff --git a/src/grammar/patterns.rs b/src/grammar/patterns.rs
index 7216807fd..770274686 100644
--- a/src/grammar/patterns.rs
+++ b/src/grammar/patterns.rs
@@ -1,14 +1,98 @@
1use super::*; 1use super::*;
2 2
3pub(super) fn pattern(p: &mut Parser) { 3pub(super) fn pattern(p: &mut Parser) {
4 match p.current() { 4 let la0 = p.nth(0);
5 let la1 = p.nth(1);
6 if la0 == REF_KW || la0 == MUT_KW
7 || (la0 == IDENT && !(la1 == COLONCOLON || la1 == L_PAREN || la1 == L_CURLY)) {
8 bind_pat(p, true);
9 return;
10 }
11 if paths::is_path_start(p) {
12 path_pat(p);
13 return;
14 }
15
16 match la0 {
5 UNDERSCORE => placeholder_pat(p), 17 UNDERSCORE => placeholder_pat(p),
6 AMPERSAND => ref_pat(p), 18 AMPERSAND => ref_pat(p),
7 IDENT | REF_KW | MUT_KW => bind_pat(p),
8 _ => p.err_and_bump("expected pattern"), 19 _ => p.err_and_bump("expected pattern"),
9 } 20 }
10} 21}
11 22
23// test path_part
24// fn foo() {
25// let foo::Bar = ();
26// let ::Bar = ();
27// let Bar { .. } = ();
28// let Bar(..) = ();
29// }
30fn path_pat(p: &mut Parser) {
31 let m = p.start();
32 paths::expr_path(p);
33 let kind = match p.current() {
34 L_PAREN => {
35 tuple_pat_fields(p);
36 TUPLE_PAT
37 }
38 L_CURLY => {
39 struct_pat_fields(p);
40 STRUCT_PAT
41 }
42 _ => PATH_PAT
43 };
44 m.complete(p, kind);
45}
46
47// test tuple_pat_fields
48// fn foo() {
49// let S() = ();
50// let S(_) = ();
51// let S(_,) = ();
52// let S(_, .. , x) = ();
53// }
54fn tuple_pat_fields(p: &mut Parser) {
55 assert!(p.at(L_PAREN));
56 p.bump();
57 while !p.at(EOF) && !p.at(R_PAREN) {
58 match p.current() {
59 DOTDOT => p.bump(),
60 _ => pattern(p),
61 }
62 if !p.at(R_PAREN) {
63 p.expect(COMMA);
64 }
65 }
66 p.expect(R_PAREN);
67}
68
69// test struct_pat_fields
70// fn foo() {
71// let S {} = ();
72// let S { f, ref mut g } = ();
73// let S { h: _, ..} = ();
74// let S { h: _, } = ();
75// }
76fn struct_pat_fields(p: &mut Parser) {
77 assert!(p.at(L_CURLY));
78 p.bump();
79 while !p.at(EOF) && !p.at(R_CURLY) {
80 match p.current() {
81 DOTDOT => p.bump(),
82 IDENT if p.nth(1) == COLON => {
83 p.bump();
84 p.bump();
85 pattern(p);
86 }
87 _ => bind_pat(p, false),
88 }
89 if !p.at(R_CURLY) {
90 p.expect(COMMA);
91 }
92 }
93 p.expect(R_CURLY);
94}
95
12// test placeholder_pat 96// test placeholder_pat
13// fn main() { let _ = (); } 97// fn main() { let _ = (); }
14fn placeholder_pat(p: &mut Parser) { 98fn placeholder_pat(p: &mut Parser) {
@@ -41,12 +125,12 @@ fn ref_pat(p: &mut Parser) {
41// let e @ _ = (); 125// let e @ _ = ();
42// let ref mut f @ g @ _ = (); 126// let ref mut f @ g @ _ = ();
43// } 127// }
44fn bind_pat(p: &mut Parser) { 128fn bind_pat(p: &mut Parser, with_at: bool) {
45 let m = p.start(); 129 let m = p.start();
46 p.eat(REF_KW); 130 p.eat(REF_KW);
47 p.eat(MUT_KW); 131 p.eat(MUT_KW);
48 name(p); 132 name(p);
49 if p.eat(AT) { 133 if with_at && p.eat(AT) {
50 pattern(p); 134 pattern(p);
51 } 135 }
52 m.complete(p, BIND_PAT); 136 m.complete(p, BIND_PAT);
diff --git a/src/syntax_kinds/generated.rs b/src/syntax_kinds/generated.rs
index 73b26b274..d7a57f4d0 100644
--- a/src/syntax_kinds/generated.rs
+++ b/src/syntax_kinds/generated.rs
@@ -118,6 +118,9 @@ pub enum SyntaxKind {
118 REF_PAT, 118 REF_PAT,
119 BIND_PAT, 119 BIND_PAT,
120 PLACEHOLDER_PAT, 120 PLACEHOLDER_PAT,
121 PATH_PAT,
122 STRUCT_PAT,
123 TUPLE_PAT,
121 TUPLE_EXPR, 124 TUPLE_EXPR,
122 PATH_EXPR, 125 PATH_EXPR,
123 CALL_EXPR, 126 CALL_EXPR,
@@ -331,6 +334,9 @@ impl SyntaxKind {
331 REF_PAT => &SyntaxInfo { name: "REF_PAT" }, 334 REF_PAT => &SyntaxInfo { name: "REF_PAT" },
332 BIND_PAT => &SyntaxInfo { name: "BIND_PAT" }, 335 BIND_PAT => &SyntaxInfo { name: "BIND_PAT" },
333 PLACEHOLDER_PAT => &SyntaxInfo { name: "PLACEHOLDER_PAT" }, 336 PLACEHOLDER_PAT => &SyntaxInfo { name: "PLACEHOLDER_PAT" },
337 PATH_PAT => &SyntaxInfo { name: "PATH_PAT" },
338 STRUCT_PAT => &SyntaxInfo { name: "STRUCT_PAT" },
339 TUPLE_PAT => &SyntaxInfo { name: "TUPLE_PAT" },
334 TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" }, 340 TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" },
335 PATH_EXPR => &SyntaxInfo { name: "PATH_EXPR" }, 341 PATH_EXPR => &SyntaxInfo { name: "PATH_EXPR" },
336 CALL_EXPR => &SyntaxInfo { name: "CALL_EXPR" }, 342 CALL_EXPR => &SyntaxInfo { name: "CALL_EXPR" },
diff --git a/tests/data/parser/inline/0071_tuple_pat_fields.rs b/tests/data/parser/inline/0071_tuple_pat_fields.rs
new file mode 100644
index 000000000..0dfe63629
--- /dev/null
+++ b/tests/data/parser/inline/0071_tuple_pat_fields.rs
@@ -0,0 +1,6 @@
1fn foo() {
2 let S() = ();
3 let S(_) = ();
4 let S(_,) = ();
5 let S(_, .. , x) = ();
6}
diff --git a/tests/data/parser/inline/0071_tuple_pat_fields.txt b/tests/data/parser/inline/0071_tuple_pat_fields.txt
new file mode 100644
index 000000000..f0b3198f5
--- /dev/null
+++ b/tests/data/parser/inline/0071_tuple_pat_fields.txt
@@ -0,0 +1,103 @@
1FILE@[0; 97)
2 FN_ITEM@[0; 97)
3 FN_KW@[0; 2)
4 NAME@[2; 6)
5 WHITESPACE@[2; 3)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 9)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK_EXPR@[9; 97)
12 L_CURLY@[9; 10)
13 LET_STMT@[10; 33)
14 WHITESPACE@[10; 15)
15 LET_KW@[15; 18)
16 TUPLE_PAT@[18; 23)
17 PATH@[18; 20)
18 PATH_SEGMENT@[18; 20)
19 NAME_REF@[18; 20)
20 WHITESPACE@[18; 19)
21 IDENT@[19; 20) "S"
22 L_PAREN@[20; 21)
23 R_PAREN@[21; 22)
24 WHITESPACE@[22; 23)
25 EQ@[23; 24)
26 TUPLE_EXPR@[24; 27)
27 WHITESPACE@[24; 25)
28 L_PAREN@[25; 26)
29 R_PAREN@[26; 27)
30 SEMI@[27; 28)
31 WHITESPACE@[28; 33)
32 LET_STMT@[33; 52)
33 LET_KW@[33; 36)
34 TUPLE_PAT@[36; 42)
35 PATH@[36; 38)
36 PATH_SEGMENT@[36; 38)
37 NAME_REF@[36; 38)
38 WHITESPACE@[36; 37)
39 IDENT@[37; 38) "S"
40 L_PAREN@[38; 39)
41 PLACEHOLDER_PAT@[39; 40)
42 UNDERSCORE@[39; 40)
43 R_PAREN@[40; 41)
44 WHITESPACE@[41; 42)
45 EQ@[42; 43)
46 TUPLE_EXPR@[43; 46)
47 WHITESPACE@[43; 44)
48 L_PAREN@[44; 45)
49 R_PAREN@[45; 46)
50 SEMI@[46; 47)
51 WHITESPACE@[47; 52)
52 LET_STMT@[52; 72)
53 LET_KW@[52; 55)
54 TUPLE_PAT@[55; 62)
55 PATH@[55; 57)
56 PATH_SEGMENT@[55; 57)
57 NAME_REF@[55; 57)
58 WHITESPACE@[55; 56)
59 IDENT@[56; 57) "S"
60 L_PAREN@[57; 58)
61 PLACEHOLDER_PAT@[58; 59)
62 UNDERSCORE@[58; 59)
63 COMMA@[59; 60)
64 R_PAREN@[60; 61)
65 WHITESPACE@[61; 62)
66 EQ@[62; 63)
67 TUPLE_EXPR@[63; 66)
68 WHITESPACE@[63; 64)
69 L_PAREN@[64; 65)
70 R_PAREN@[65; 66)
71 SEMI@[66; 67)
72 WHITESPACE@[67; 72)
73 LET_STMT@[72; 95)
74 LET_KW@[72; 75)
75 TUPLE_PAT@[75; 89)
76 PATH@[75; 77)
77 PATH_SEGMENT@[75; 77)
78 NAME_REF@[75; 77)
79 WHITESPACE@[75; 76)
80 IDENT@[76; 77) "S"
81 L_PAREN@[77; 78)
82 PLACEHOLDER_PAT@[78; 79)
83 UNDERSCORE@[78; 79)
84 COMMA@[79; 80)
85 WHITESPACE@[80; 81)
86 DOTDOT@[81; 83)
87 WHITESPACE@[83; 84)
88 COMMA@[84; 85)
89 BIND_PAT@[85; 87)
90 NAME@[85; 87)
91 WHITESPACE@[85; 86)
92 IDENT@[86; 87) "x"
93 R_PAREN@[87; 88)
94 WHITESPACE@[88; 89)
95 EQ@[89; 90)
96 TUPLE_EXPR@[90; 93)
97 WHITESPACE@[90; 91)
98 L_PAREN@[91; 92)
99 R_PAREN@[92; 93)
100 SEMI@[93; 94)
101 WHITESPACE@[94; 95)
102 R_CURLY@[95; 96)
103 WHITESPACE@[96; 97)
diff --git a/tests/data/parser/inline/0072_path_part.rs b/tests/data/parser/inline/0072_path_part.rs
new file mode 100644
index 000000000..f6e32c7c1
--- /dev/null
+++ b/tests/data/parser/inline/0072_path_part.rs
@@ -0,0 +1,6 @@
1fn foo() {
2 let foo::Bar = ();
3 let ::Bar = ();
4 let Bar { .. } = ();
5 let Bar(..) = ();
6}
diff --git a/tests/data/parser/inline/0072_path_part.txt b/tests/data/parser/inline/0072_path_part.txt
new file mode 100644
index 000000000..227046fcc
--- /dev/null
+++ b/tests/data/parser/inline/0072_path_part.txt
@@ -0,0 +1,94 @@
1FILE@[0; 103)
2 FN_ITEM@[0; 103)
3 FN_KW@[0; 2)
4 NAME@[2; 6)
5 WHITESPACE@[2; 3)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 9)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK_EXPR@[9; 103)
12 L_CURLY@[9; 10)
13 LET_STMT@[10; 38)
14 WHITESPACE@[10; 15)
15 LET_KW@[15; 18)
16 PATH_PAT@[18; 28)
17 PATH@[18; 28)
18 PATH@[18; 22)
19 PATH_SEGMENT@[18; 22)
20 NAME_REF@[18; 22)
21 WHITESPACE@[18; 19)
22 IDENT@[19; 22) "foo"
23 COLONCOLON@[22; 24)
24 PATH_SEGMENT@[24; 28)
25 NAME_REF@[24; 28)
26 IDENT@[24; 27) "Bar"
27 WHITESPACE@[27; 28)
28 EQ@[28; 29)
29 TUPLE_EXPR@[29; 32)
30 WHITESPACE@[29; 30)
31 L_PAREN@[30; 31)
32 R_PAREN@[31; 32)
33 SEMI@[32; 33)
34 WHITESPACE@[33; 38)
35 LET_STMT@[38; 58)
36 LET_KW@[38; 41)
37 PATH_PAT@[41; 48)
38 PATH@[41; 48)
39 PATH_SEGMENT@[41; 48)
40 WHITESPACE@[41; 42)
41 COLONCOLON@[42; 44)
42 NAME_REF@[44; 48)
43 IDENT@[44; 47) "Bar"
44 WHITESPACE@[47; 48)
45 EQ@[48; 49)
46 TUPLE_EXPR@[49; 52)
47 WHITESPACE@[49; 50)
48 L_PAREN@[50; 51)
49 R_PAREN@[51; 52)
50 SEMI@[52; 53)
51 WHITESPACE@[53; 58)
52 LET_STMT@[58; 83)
53 LET_KW@[58; 61)
54 STRUCT_PAT@[61; 73)
55 PATH@[61; 66)
56 PATH_SEGMENT@[61; 66)
57 NAME_REF@[61; 66)
58 WHITESPACE@[61; 62)
59 IDENT@[62; 65) "Bar"
60 WHITESPACE@[65; 66)
61 L_CURLY@[66; 67)
62 WHITESPACE@[67; 68)
63 DOTDOT@[68; 70)
64 WHITESPACE@[70; 71)
65 R_CURLY@[71; 72)
66 WHITESPACE@[72; 73)
67 EQ@[73; 74)
68 TUPLE_EXPR@[74; 77)
69 WHITESPACE@[74; 75)
70 L_PAREN@[75; 76)
71 R_PAREN@[76; 77)
72 SEMI@[77; 78)
73 WHITESPACE@[78; 83)
74 LET_STMT@[83; 101)
75 LET_KW@[83; 86)
76 TUPLE_PAT@[86; 95)
77 PATH@[86; 90)
78 PATH_SEGMENT@[86; 90)
79 NAME_REF@[86; 90)
80 WHITESPACE@[86; 87)
81 IDENT@[87; 90) "Bar"
82 L_PAREN@[90; 91)
83 DOTDOT@[91; 93)
84 R_PAREN@[93; 94)
85 WHITESPACE@[94; 95)
86 EQ@[95; 96)
87 TUPLE_EXPR@[96; 99)
88 WHITESPACE@[96; 97)
89 L_PAREN@[97; 98)
90 R_PAREN@[98; 99)
91 SEMI@[99; 100)
92 WHITESPACE@[100; 101)
93 R_CURLY@[101; 102)
94 WHITESPACE@[102; 103)
diff --git a/tests/data/parser/inline/0073_struct_pat_fields.rs b/tests/data/parser/inline/0073_struct_pat_fields.rs
new file mode 100644
index 000000000..da3412fa8
--- /dev/null
+++ b/tests/data/parser/inline/0073_struct_pat_fields.rs
@@ -0,0 +1,6 @@
1fn foo() {
2 let S {} = ();
3 let S { f, ref mut g } = ();
4 let S { h: _, ..} = ();
5 let S { h: _, } = ();
6}
diff --git a/tests/data/parser/inline/0073_struct_pat_fields.txt b/tests/data/parser/inline/0073_struct_pat_fields.txt
new file mode 100644
index 000000000..639c34dcb
--- /dev/null
+++ b/tests/data/parser/inline/0073_struct_pat_fields.txt
@@ -0,0 +1,122 @@
1FILE@[0; 119)
2 FN_ITEM@[0; 119)
3 FN_KW@[0; 2)
4 NAME@[2; 6)
5 WHITESPACE@[2; 3)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 9)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK_EXPR@[9; 119)
12 L_CURLY@[9; 10)
13 LET_STMT@[10; 34)
14 WHITESPACE@[10; 15)
15 LET_KW@[15; 18)
16 STRUCT_PAT@[18; 24)
17 PATH@[18; 21)
18 PATH_SEGMENT@[18; 21)
19 NAME_REF@[18; 21)
20 WHITESPACE@[18; 19)
21 IDENT@[19; 20) "S"
22 WHITESPACE@[20; 21)
23 L_CURLY@[21; 22)
24 R_CURLY@[22; 23)
25 WHITESPACE@[23; 24)
26 EQ@[24; 25)
27 TUPLE_EXPR@[25; 28)
28 WHITESPACE@[25; 26)
29 L_PAREN@[26; 27)
30 R_PAREN@[27; 28)
31 SEMI@[28; 29)
32 WHITESPACE@[29; 34)
33 LET_STMT@[34; 67)
34 LET_KW@[34; 37)
35 STRUCT_PAT@[37; 57)
36 PATH@[37; 40)
37 PATH_SEGMENT@[37; 40)
38 NAME_REF@[37; 40)
39 WHITESPACE@[37; 38)
40 IDENT@[38; 39) "S"
41 WHITESPACE@[39; 40)
42 L_CURLY@[40; 41)
43 BIND_PAT@[41; 43)
44 NAME@[41; 43)
45 WHITESPACE@[41; 42)
46 IDENT@[42; 43) "f"
47 COMMA@[43; 44)
48 BIND_PAT@[44; 55)
49 WHITESPACE@[44; 45)
50 REF_KW@[45; 48)
51 WHITESPACE@[48; 49)
52 MUT_KW@[49; 52)
53 NAME@[52; 55)
54 WHITESPACE@[52; 53)
55 IDENT@[53; 54) "g"
56 WHITESPACE@[54; 55)
57 R_CURLY@[55; 56)
58 WHITESPACE@[56; 57)
59 EQ@[57; 58)
60 TUPLE_EXPR@[58; 61)
61 WHITESPACE@[58; 59)
62 L_PAREN@[59; 60)
63 R_PAREN@[60; 61)
64 SEMI@[61; 62)
65 WHITESPACE@[62; 67)
66 LET_STMT@[67; 95)
67 LET_KW@[67; 70)
68 STRUCT_PAT@[70; 85)
69 PATH@[70; 73)
70 PATH_SEGMENT@[70; 73)
71 NAME_REF@[70; 73)
72 WHITESPACE@[70; 71)
73 IDENT@[71; 72) "S"
74 WHITESPACE@[72; 73)
75 L_CURLY@[73; 74)
76 WHITESPACE@[74; 75)
77 IDENT@[75; 76) "h"
78 COLON@[76; 77)
79 PLACEHOLDER_PAT@[77; 79)
80 WHITESPACE@[77; 78)
81 UNDERSCORE@[78; 79)
82 COMMA@[79; 80)
83 WHITESPACE@[80; 81)
84 DOTDOT@[81; 83)
85 R_CURLY@[83; 84)
86 WHITESPACE@[84; 85)
87 EQ@[85; 86)
88 TUPLE_EXPR@[86; 89)
89 WHITESPACE@[86; 87)
90 L_PAREN@[87; 88)
91 R_PAREN@[88; 89)
92 SEMI@[89; 90)
93 WHITESPACE@[90; 95)
94 LET_STMT@[95; 117)
95 LET_KW@[95; 98)
96 STRUCT_PAT@[98; 111)
97 PATH@[98; 101)
98 PATH_SEGMENT@[98; 101)
99 NAME_REF@[98; 101)
100 WHITESPACE@[98; 99)
101 IDENT@[99; 100) "S"
102 WHITESPACE@[100; 101)
103 L_CURLY@[101; 102)
104 WHITESPACE@[102; 103)
105 IDENT@[103; 104) "h"
106 COLON@[104; 105)
107 PLACEHOLDER_PAT@[105; 107)
108 WHITESPACE@[105; 106)
109 UNDERSCORE@[106; 107)
110 COMMA@[107; 108)
111 WHITESPACE@[108; 109)
112 R_CURLY@[109; 110)
113 WHITESPACE@[110; 111)
114 EQ@[111; 112)
115 TUPLE_EXPR@[112; 115)
116 WHITESPACE@[112; 113)
117 L_PAREN@[113; 114)
118 R_PAREN@[114; 115)
119 SEMI@[115; 116)
120 WHITESPACE@[116; 117)
121 R_CURLY@[117; 118)
122 WHITESPACE@[118; 119)