Skip to content

Commit f8000ad

Browse files
Undinrrevenantt
authored andcommitted
GRAM: support if_while_or_patterns syntax
See rust-lang/rust#57532 for more details
1 parent 74ee70f commit f8000ad

File tree

9 files changed

+423
-55
lines changed

9 files changed

+423
-55
lines changed

src/main/grammars/RustParser.bnf

+5-3
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,8 @@ PatField ::= identifier ':' Pat | box? PatBinding
485485

486486
BindingMode ::= ref mut? | mut
487487

488+
OrPats ::= '|'? Pat ('|' Pat)*
489+
488490
Constant ::= OuterAttr* default_? Vis? (static mut? | const) identifier TypeAscription [ '=' AnyExpr ] ';' {
489491
pin = 'identifier'
490492
implements = [ "org.rust.lang.core.psi.ext.RsQualifiedNamedElement"
@@ -1027,7 +1029,7 @@ WhileExpr ::= OuterAttr* LabelDecl? while Condition SimpleBlock {
10271029
implements = [ "org.rust.lang.core.psi.ext.RsLabeledExpression" ]
10281030
elementTypeFactory = "org.rust.lang.core.stubs.StubImplementationsKt.factory"
10291031
}
1030-
Condition ::= [ let Pat '=' ] NoStructLitExpr
1032+
Condition ::= [ let OrPats '=' ] NoStructLitExpr
10311033

10321034
LoopExpr ::= OuterAttr* LabelDecl? loop SimpleBlock {
10331035
pin = 'loop'
@@ -1063,8 +1065,8 @@ MatchExpr ::= OuterAttr* match NoStructLitExpr MatchBody {
10631065
elementTypeFactory = "org.rust.lang.core.stubs.StubImplementationsKt.factory"
10641066
}
10651067
MatchBody ::= '{' MatchArm* '}' { pin = 1 }
1066-
MatchArm ::= OuterAttr* '|'? Pat ('|' Pat)* MatchArmGuard? '=>' StmtModeExpr (',' | (&'}' | <<isBlock>>)) {
1067-
pin = 3
1068+
MatchArm ::= OuterAttr* OrPats MatchArmGuard? '=>' StmtModeExpr (',' | (&'}' | <<isBlock>>)) {
1069+
pin = 2
10681070
recoverWhile = MatchArm_recover
10691071
}
10701072
private MatchArm_recover ::= !(Pat_first | OuterAttr_first | '}' | '|')

src/test/kotlin/org/rust/lang/core/parser/RsCompleteParsingTestCase.kt

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class RsCompleteParsingTestCase : RsParsingTestCaseBase("complete") {
4747
fun `test visibility`() = doTest(true)
4848
fun `test polybounds`() = doTest(true)
4949
fun `test async await`() = doTest(true)
50+
fun `test conditions`() = doTest(true)
5051

5152
fun `test issue320`() = doTest(true)
5253
fun `test diesel macros`() = doTest(true)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
fn main() {
2+
if 1 < 2 {}
3+
if let Some(x) = o {}
4+
if let | Err(e) = r {}
5+
if let V1(s) | V2(s) = value {}
6+
if let | Cat(name) | Dog(name) | Parrot(name) = animal {}
7+
8+
while 1 < 2 {}
9+
while let Some(x) = o {}
10+
while let | Err(e) = r {}
11+
while let V1(s) | V2(s) = value {}
12+
while let | Cat(name) | Dog(name) | Parrot(name) = animal {}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,340 @@
1+
FILE
2+
RsFunctionImpl(FUNCTION)
3+
PsiElement(fn)('fn')
4+
PsiWhiteSpace(' ')
5+
PsiElement(identifier)('main')
6+
RsValueParameterListImpl(VALUE_PARAMETER_LIST)
7+
PsiElement(()('(')
8+
PsiElement())(')')
9+
PsiWhiteSpace(' ')
10+
RsBlockImpl(BLOCK)
11+
PsiElement({)('{')
12+
PsiWhiteSpace('\n ')
13+
RsExprStmtImpl(EXPR_STMT)
14+
RsIfExprImpl(IF_EXPR)
15+
PsiElement(if)('if')
16+
PsiWhiteSpace(' ')
17+
RsConditionImpl(CONDITION)
18+
RsBinaryExprImpl(BINARY_EXPR)
19+
RsLitExprImpl(LIT_EXPR)
20+
PsiElement(INTEGER_LITERAL)('1')
21+
PsiWhiteSpace(' ')
22+
RsBinaryOpImpl(BINARY_OP)
23+
PsiElement(<)('<')
24+
PsiWhiteSpace(' ')
25+
RsLitExprImpl(LIT_EXPR)
26+
PsiElement(INTEGER_LITERAL)('2')
27+
PsiWhiteSpace(' ')
28+
RsBlockImpl(BLOCK)
29+
PsiElement({)('{')
30+
PsiElement(})('}')
31+
PsiWhiteSpace('\n ')
32+
RsExprStmtImpl(EXPR_STMT)
33+
RsIfExprImpl(IF_EXPR)
34+
PsiElement(if)('if')
35+
PsiWhiteSpace(' ')
36+
RsConditionImpl(CONDITION)
37+
PsiElement(let)('let')
38+
PsiWhiteSpace(' ')
39+
RsOrPatsImpl(OR_PATS)
40+
RsPatTupleStructImpl(PAT_TUPLE_STRUCT)
41+
RsPathImpl(PATH)
42+
PsiElement(identifier)('Some')
43+
PsiElement(()('(')
44+
RsPatIdentImpl(PAT_IDENT)
45+
RsPatBindingImpl(PAT_BINDING)
46+
PsiElement(identifier)('x')
47+
PsiElement())(')')
48+
PsiWhiteSpace(' ')
49+
PsiElement(=)('=')
50+
PsiWhiteSpace(' ')
51+
RsPathExprImpl(PATH_EXPR)
52+
RsPathImpl(PATH)
53+
PsiElement(identifier)('o')
54+
PsiWhiteSpace(' ')
55+
RsBlockImpl(BLOCK)
56+
PsiElement({)('{')
57+
PsiElement(})('}')
58+
PsiWhiteSpace('\n ')
59+
RsExprStmtImpl(EXPR_STMT)
60+
RsIfExprImpl(IF_EXPR)
61+
PsiElement(if)('if')
62+
PsiWhiteSpace(' ')
63+
RsConditionImpl(CONDITION)
64+
PsiElement(let)('let')
65+
PsiWhiteSpace(' ')
66+
RsOrPatsImpl(OR_PATS)
67+
PsiElement(|)('|')
68+
PsiWhiteSpace(' ')
69+
RsPatTupleStructImpl(PAT_TUPLE_STRUCT)
70+
RsPathImpl(PATH)
71+
PsiElement(identifier)('Err')
72+
PsiElement(()('(')
73+
RsPatIdentImpl(PAT_IDENT)
74+
RsPatBindingImpl(PAT_BINDING)
75+
PsiElement(identifier)('e')
76+
PsiElement())(')')
77+
PsiWhiteSpace(' ')
78+
PsiElement(=)('=')
79+
PsiWhiteSpace(' ')
80+
RsPathExprImpl(PATH_EXPR)
81+
RsPathImpl(PATH)
82+
PsiElement(identifier)('r')
83+
PsiWhiteSpace(' ')
84+
RsBlockImpl(BLOCK)
85+
PsiElement({)('{')
86+
PsiElement(})('}')
87+
PsiWhiteSpace('\n ')
88+
RsExprStmtImpl(EXPR_STMT)
89+
RsIfExprImpl(IF_EXPR)
90+
PsiElement(if)('if')
91+
PsiWhiteSpace(' ')
92+
RsConditionImpl(CONDITION)
93+
PsiElement(let)('let')
94+
PsiWhiteSpace(' ')
95+
RsOrPatsImpl(OR_PATS)
96+
RsPatTupleStructImpl(PAT_TUPLE_STRUCT)
97+
RsPathImpl(PATH)
98+
PsiElement(identifier)('V1')
99+
PsiElement(()('(')
100+
RsPatIdentImpl(PAT_IDENT)
101+
RsPatBindingImpl(PAT_BINDING)
102+
PsiElement(identifier)('s')
103+
PsiElement())(')')
104+
PsiWhiteSpace(' ')
105+
PsiElement(|)('|')
106+
PsiWhiteSpace(' ')
107+
RsPatTupleStructImpl(PAT_TUPLE_STRUCT)
108+
RsPathImpl(PATH)
109+
PsiElement(identifier)('V2')
110+
PsiElement(()('(')
111+
RsPatIdentImpl(PAT_IDENT)
112+
RsPatBindingImpl(PAT_BINDING)
113+
PsiElement(identifier)('s')
114+
PsiElement())(')')
115+
PsiWhiteSpace(' ')
116+
PsiElement(=)('=')
117+
PsiWhiteSpace(' ')
118+
RsPathExprImpl(PATH_EXPR)
119+
RsPathImpl(PATH)
120+
PsiElement(identifier)('value')
121+
PsiWhiteSpace(' ')
122+
RsBlockImpl(BLOCK)
123+
PsiElement({)('{')
124+
PsiElement(})('}')
125+
PsiWhiteSpace('\n ')
126+
RsExprStmtImpl(EXPR_STMT)
127+
RsIfExprImpl(IF_EXPR)
128+
PsiElement(if)('if')
129+
PsiWhiteSpace(' ')
130+
RsConditionImpl(CONDITION)
131+
PsiElement(let)('let')
132+
PsiWhiteSpace(' ')
133+
RsOrPatsImpl(OR_PATS)
134+
PsiElement(|)('|')
135+
PsiWhiteSpace(' ')
136+
RsPatTupleStructImpl(PAT_TUPLE_STRUCT)
137+
RsPathImpl(PATH)
138+
PsiElement(identifier)('Cat')
139+
PsiElement(()('(')
140+
RsPatIdentImpl(PAT_IDENT)
141+
RsPatBindingImpl(PAT_BINDING)
142+
PsiElement(identifier)('name')
143+
PsiElement())(')')
144+
PsiWhiteSpace(' ')
145+
PsiElement(|)('|')
146+
PsiWhiteSpace(' ')
147+
RsPatTupleStructImpl(PAT_TUPLE_STRUCT)
148+
RsPathImpl(PATH)
149+
PsiElement(identifier)('Dog')
150+
PsiElement(()('(')
151+
RsPatIdentImpl(PAT_IDENT)
152+
RsPatBindingImpl(PAT_BINDING)
153+
PsiElement(identifier)('name')
154+
PsiElement())(')')
155+
PsiWhiteSpace(' ')
156+
PsiElement(|)('|')
157+
PsiWhiteSpace(' ')
158+
RsPatTupleStructImpl(PAT_TUPLE_STRUCT)
159+
RsPathImpl(PATH)
160+
PsiElement(identifier)('Parrot')
161+
PsiElement(()('(')
162+
RsPatIdentImpl(PAT_IDENT)
163+
RsPatBindingImpl(PAT_BINDING)
164+
PsiElement(identifier)('name')
165+
PsiElement())(')')
166+
PsiWhiteSpace(' ')
167+
PsiElement(=)('=')
168+
PsiWhiteSpace(' ')
169+
RsPathExprImpl(PATH_EXPR)
170+
RsPathImpl(PATH)
171+
PsiElement(identifier)('animal')
172+
PsiWhiteSpace(' ')
173+
RsBlockImpl(BLOCK)
174+
PsiElement({)('{')
175+
PsiElement(})('}')
176+
PsiWhiteSpace('\n\n ')
177+
RsExprStmtImpl(EXPR_STMT)
178+
RsWhileExprImpl(WHILE_EXPR)
179+
PsiElement(while)('while')
180+
PsiWhiteSpace(' ')
181+
RsConditionImpl(CONDITION)
182+
RsBinaryExprImpl(BINARY_EXPR)
183+
RsLitExprImpl(LIT_EXPR)
184+
PsiElement(INTEGER_LITERAL)('1')
185+
PsiWhiteSpace(' ')
186+
RsBinaryOpImpl(BINARY_OP)
187+
PsiElement(<)('<')
188+
PsiWhiteSpace(' ')
189+
RsLitExprImpl(LIT_EXPR)
190+
PsiElement(INTEGER_LITERAL)('2')
191+
PsiWhiteSpace(' ')
192+
RsBlockImpl(BLOCK)
193+
PsiElement({)('{')
194+
PsiElement(})('}')
195+
PsiWhiteSpace('\n ')
196+
RsExprStmtImpl(EXPR_STMT)
197+
RsWhileExprImpl(WHILE_EXPR)
198+
PsiElement(while)('while')
199+
PsiWhiteSpace(' ')
200+
RsConditionImpl(CONDITION)
201+
PsiElement(let)('let')
202+
PsiWhiteSpace(' ')
203+
RsOrPatsImpl(OR_PATS)
204+
RsPatTupleStructImpl(PAT_TUPLE_STRUCT)
205+
RsPathImpl(PATH)
206+
PsiElement(identifier)('Some')
207+
PsiElement(()('(')
208+
RsPatIdentImpl(PAT_IDENT)
209+
RsPatBindingImpl(PAT_BINDING)
210+
PsiElement(identifier)('x')
211+
PsiElement())(')')
212+
PsiWhiteSpace(' ')
213+
PsiElement(=)('=')
214+
PsiWhiteSpace(' ')
215+
RsPathExprImpl(PATH_EXPR)
216+
RsPathImpl(PATH)
217+
PsiElement(identifier)('o')
218+
PsiWhiteSpace(' ')
219+
RsBlockImpl(BLOCK)
220+
PsiElement({)('{')
221+
PsiElement(})('}')
222+
PsiWhiteSpace('\n ')
223+
RsExprStmtImpl(EXPR_STMT)
224+
RsWhileExprImpl(WHILE_EXPR)
225+
PsiElement(while)('while')
226+
PsiWhiteSpace(' ')
227+
RsConditionImpl(CONDITION)
228+
PsiElement(let)('let')
229+
PsiWhiteSpace(' ')
230+
RsOrPatsImpl(OR_PATS)
231+
PsiElement(|)('|')
232+
PsiWhiteSpace(' ')
233+
RsPatTupleStructImpl(PAT_TUPLE_STRUCT)
234+
RsPathImpl(PATH)
235+
PsiElement(identifier)('Err')
236+
PsiElement(()('(')
237+
RsPatIdentImpl(PAT_IDENT)
238+
RsPatBindingImpl(PAT_BINDING)
239+
PsiElement(identifier)('e')
240+
PsiElement())(')')
241+
PsiWhiteSpace(' ')
242+
PsiElement(=)('=')
243+
PsiWhiteSpace(' ')
244+
RsPathExprImpl(PATH_EXPR)
245+
RsPathImpl(PATH)
246+
PsiElement(identifier)('r')
247+
PsiWhiteSpace(' ')
248+
RsBlockImpl(BLOCK)
249+
PsiElement({)('{')
250+
PsiElement(})('}')
251+
PsiWhiteSpace('\n ')
252+
RsExprStmtImpl(EXPR_STMT)
253+
RsWhileExprImpl(WHILE_EXPR)
254+
PsiElement(while)('while')
255+
PsiWhiteSpace(' ')
256+
RsConditionImpl(CONDITION)
257+
PsiElement(let)('let')
258+
PsiWhiteSpace(' ')
259+
RsOrPatsImpl(OR_PATS)
260+
RsPatTupleStructImpl(PAT_TUPLE_STRUCT)
261+
RsPathImpl(PATH)
262+
PsiElement(identifier)('V1')
263+
PsiElement(()('(')
264+
RsPatIdentImpl(PAT_IDENT)
265+
RsPatBindingImpl(PAT_BINDING)
266+
PsiElement(identifier)('s')
267+
PsiElement())(')')
268+
PsiWhiteSpace(' ')
269+
PsiElement(|)('|')
270+
PsiWhiteSpace(' ')
271+
RsPatTupleStructImpl(PAT_TUPLE_STRUCT)
272+
RsPathImpl(PATH)
273+
PsiElement(identifier)('V2')
274+
PsiElement(()('(')
275+
RsPatIdentImpl(PAT_IDENT)
276+
RsPatBindingImpl(PAT_BINDING)
277+
PsiElement(identifier)('s')
278+
PsiElement())(')')
279+
PsiWhiteSpace(' ')
280+
PsiElement(=)('=')
281+
PsiWhiteSpace(' ')
282+
RsPathExprImpl(PATH_EXPR)
283+
RsPathImpl(PATH)
284+
PsiElement(identifier)('value')
285+
PsiWhiteSpace(' ')
286+
RsBlockImpl(BLOCK)
287+
PsiElement({)('{')
288+
PsiElement(})('}')
289+
PsiWhiteSpace('\n ')
290+
RsWhileExprImpl(WHILE_EXPR)
291+
PsiElement(while)('while')
292+
PsiWhiteSpace(' ')
293+
RsConditionImpl(CONDITION)
294+
PsiElement(let)('let')
295+
PsiWhiteSpace(' ')
296+
RsOrPatsImpl(OR_PATS)
297+
PsiElement(|)('|')
298+
PsiWhiteSpace(' ')
299+
RsPatTupleStructImpl(PAT_TUPLE_STRUCT)
300+
RsPathImpl(PATH)
301+
PsiElement(identifier)('Cat')
302+
PsiElement(()('(')
303+
RsPatIdentImpl(PAT_IDENT)
304+
RsPatBindingImpl(PAT_BINDING)
305+
PsiElement(identifier)('name')
306+
PsiElement())(')')
307+
PsiWhiteSpace(' ')
308+
PsiElement(|)('|')
309+
PsiWhiteSpace(' ')
310+
RsPatTupleStructImpl(PAT_TUPLE_STRUCT)
311+
RsPathImpl(PATH)
312+
PsiElement(identifier)('Dog')
313+
PsiElement(()('(')
314+
RsPatIdentImpl(PAT_IDENT)
315+
RsPatBindingImpl(PAT_BINDING)
316+
PsiElement(identifier)('name')
317+
PsiElement())(')')
318+
PsiWhiteSpace(' ')
319+
PsiElement(|)('|')
320+
PsiWhiteSpace(' ')
321+
RsPatTupleStructImpl(PAT_TUPLE_STRUCT)
322+
RsPathImpl(PATH)
323+
PsiElement(identifier)('Parrot')
324+
PsiElement(()('(')
325+
RsPatIdentImpl(PAT_IDENT)
326+
RsPatBindingImpl(PAT_BINDING)
327+
PsiElement(identifier)('name')
328+
PsiElement())(')')
329+
PsiWhiteSpace(' ')
330+
PsiElement(=)('=')
331+
PsiWhiteSpace(' ')
332+
RsPathExprImpl(PATH_EXPR)
333+
RsPathImpl(PATH)
334+
PsiElement(identifier)('animal')
335+
PsiWhiteSpace(' ')
336+
RsBlockImpl(BLOCK)
337+
PsiElement({)('{')
338+
PsiElement(})('}')
339+
PsiWhiteSpace('\n')
340+
PsiElement(})('}')

0 commit comments

Comments
 (0)