microsoft/qdk

Public

mirrored fromhttps://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.0.33

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

compiler/qsc_parse/src/stmt/tests.rs

853lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use super::{parse, parse_block};
5use crate::tests::check;
6use expect_test::expect;
7
8#[test]
9fn empty_stmt() {
10 check(parse, ";", &expect!["Stmt _id_ [0-1]: Empty"]);
11}
12
13#[test]
14fn let_stmt() {
15 check(
16 parse,
17 "let x = 2;",
18 &expect![[r#"
19 Stmt _id_ [0-10]: Local (Immutable):
20 Pat _id_ [4-5]: Bind:
21 Ident _id_ [4-5] "x"
22 Expr _id_ [8-9]: Lit: Int(2)"#]],
23 );
24}
25
26#[test]
27fn let_pat_match() {
28 check(
29 parse,
30 "let (x, (y, z)) = foo;",
31 &expect![[r#"
32 Stmt _id_ [0-22]: Local (Immutable):
33 Pat _id_ [4-15]: Tuple:
34 Pat _id_ [5-6]: Bind:
35 Ident _id_ [5-6] "x"
36 Pat _id_ [8-14]: Tuple:
37 Pat _id_ [9-10]: Bind:
38 Ident _id_ [9-10] "y"
39 Pat _id_ [12-13]: Bind:
40 Ident _id_ [12-13] "z"
41 Expr _id_ [18-21]: Path: Path _id_ [18-21] (Ident _id_ [18-21] "foo")"#]],
42 );
43}
44
45#[test]
46fn mutable_stmt() {
47 check(
48 parse,
49 "mutable x = 2;",
50 &expect![[r#"
51 Stmt _id_ [0-14]: Local (Mutable):
52 Pat _id_ [8-9]: Bind:
53 Ident _id_ [8-9] "x"
54 Expr _id_ [12-13]: Lit: Int(2)"#]],
55 );
56}
57
58#[test]
59fn use_stmt() {
60 check(
61 parse,
62 "use q = Qubit();",
63 &expect![[r#"
64 Stmt _id_ [0-16]: Qubit (Fresh)
65 Pat _id_ [4-5]: Bind:
66 Ident _id_ [4-5] "q"
67 QubitInit _id_ [8-15] Single"#]],
68 );
69}
70
71#[test]
72fn use_qubit_array() {
73 check(
74 parse,
75 "use qs = Qubit[5];",
76 &expect![[r#"
77 Stmt _id_ [0-18]: Qubit (Fresh)
78 Pat _id_ [4-6]: Bind:
79 Ident _id_ [4-6] "qs"
80 QubitInit _id_ [9-17] Array:
81 Expr _id_ [15-16]: Lit: Int(5)"#]],
82 );
83}
84
85#[test]
86fn use_pat_match() {
87 check(
88 parse,
89 "use (q1, q2) = (Qubit(), Qubit());",
90 &expect![[r#"
91 Stmt _id_ [0-34]: Qubit (Fresh)
92 Pat _id_ [4-12]: Tuple:
93 Pat _id_ [5-7]: Bind:
94 Ident _id_ [5-7] "q1"
95 Pat _id_ [9-11]: Bind:
96 Ident _id_ [9-11] "q2"
97 QubitInit _id_ [15-33] Tuple:
98 QubitInit _id_ [16-23] Single
99 QubitInit _id_ [25-32] Single"#]],
100 );
101}
102
103#[test]
104fn use_paren() {
105 check(
106 parse,
107 "use q = (Qubit());",
108 &expect![[r#"
109 Stmt _id_ [0-18]: Qubit (Fresh)
110 Pat _id_ [4-5]: Bind:
111 Ident _id_ [4-5] "q"
112 QubitInit _id_ [8-17] Parens:
113 QubitInit _id_ [9-16] Single"#]],
114 );
115}
116
117#[test]
118fn use_single_tuple() {
119 check(
120 parse,
121 "use (q,) = (Qubit(),);",
122 &expect![[r#"
123 Stmt _id_ [0-22]: Qubit (Fresh)
124 Pat _id_ [4-8]: Tuple:
125 Pat _id_ [5-6]: Bind:
126 Ident _id_ [5-6] "q"
127 QubitInit _id_ [11-21] Tuple:
128 QubitInit _id_ [12-19] Single"#]],
129 );
130}
131
132#[test]
133fn use_invalid_init() {
134 check(
135 parse,
136 "use q = Qutrit();",
137 &expect![[r#"
138 Error(
139 Convert(
140 "qubit initializer",
141 "identifier",
142 Span {
143 lo: 8,
144 hi: 14,
145 },
146 ),
147 )
148 "#]],
149 );
150}
151
152#[test]
153fn use_tuple_duplicate_commas() {
154 check(
155 parse,
156 "use (q1,, q2) = (Qubit(),, Qubit());",
157 &expect![[r#"
158 Stmt _id_ [0-36]: Qubit (Fresh)
159 Pat _id_ [4-13]: Tuple:
160 Pat _id_ [5-7]: Bind:
161 Ident _id_ [5-7] "q1"
162 Pat _id_ [8-8]: Err
163 Pat _id_ [10-12]: Bind:
164 Ident _id_ [10-12] "q2"
165 QubitInit _id_ [16-35] Tuple:
166 QubitInit _id_ [17-24] Single
167 QubitInit _id_ [25-25] Err
168 QubitInit _id_ [27-34] Single
169
170 [
171 Error(
172 MissingSeqEntry(
173 Span {
174 lo: 8,
175 hi: 8,
176 },
177 ),
178 ),
179 Error(
180 MissingSeqEntry(
181 Span {
182 lo: 25,
183 hi: 25,
184 },
185 ),
186 ),
187 ]"#]],
188 );
189}
190
191#[test]
192fn use_tuple_initial_commas() {
193 check(
194 parse,
195 "use (,, q1, q2) = (, Qubit(), Qubit());",
196 &expect![[r#"
197 Stmt _id_ [0-39]: Qubit (Fresh)
198 Pat _id_ [4-15]: Tuple:
199 Pat _id_ [5-5]: Err
200 Pat _id_ [6-6]: Err
201 Pat _id_ [8-10]: Bind:
202 Ident _id_ [8-10] "q1"
203 Pat _id_ [12-14]: Bind:
204 Ident _id_ [12-14] "q2"
205 QubitInit _id_ [18-38] Tuple:
206 QubitInit _id_ [19-19] Err
207 QubitInit _id_ [21-28] Single
208 QubitInit _id_ [30-37] Single
209
210 [
211 Error(
212 MissingSeqEntry(
213 Span {
214 lo: 5,
215 hi: 5,
216 },
217 ),
218 ),
219 Error(
220 MissingSeqEntry(
221 Span {
222 lo: 6,
223 hi: 6,
224 },
225 ),
226 ),
227 Error(
228 MissingSeqEntry(
229 Span {
230 lo: 19,
231 hi: 19,
232 },
233 ),
234 ),
235 ]"#]],
236 );
237}
238
239#[test]
240fn borrow_stmt() {
241 check(
242 parse,
243 "borrow q = Qubit();",
244 &expect![[r#"
245 Stmt _id_ [0-19]: Qubit (Dirty)
246 Pat _id_ [7-8]: Bind:
247 Ident _id_ [7-8] "q"
248 QubitInit _id_ [11-18] Single"#]],
249 );
250}
251
252#[test]
253fn let_in_block() {
254 check(
255 parse_block,
256 "{ let x = 2; x }",
257 &expect![[r#"
258 Block _id_ [0-16]:
259 Stmt _id_ [2-12]: Local (Immutable):
260 Pat _id_ [6-7]: Bind:
261 Ident _id_ [6-7] "x"
262 Expr _id_ [10-11]: Lit: Int(2)
263 Stmt _id_ [13-14]: Expr: Expr _id_ [13-14]: Path: Path _id_ [13-14] (Ident _id_ [13-14] "x")"#]],
264 );
265}
266
267#[test]
268fn exprs_in_block() {
269 check(
270 parse_block,
271 "{ x; y; z }",
272 &expect![[r#"
273 Block _id_ [0-11]:
274 Stmt _id_ [2-4]: Semi: Expr _id_ [2-3]: Path: Path _id_ [2-3] (Ident _id_ [2-3] "x")
275 Stmt _id_ [5-7]: Semi: Expr _id_ [5-6]: Path: Path _id_ [5-6] (Ident _id_ [5-6] "y")
276 Stmt _id_ [8-9]: Expr: Expr _id_ [8-9]: Path: Path _id_ [8-9] (Ident _id_ [8-9] "z")"#]],
277 );
278}
279
280#[test]
281fn trailing_semi_expr() {
282 check(
283 parse_block,
284 "{ x; y; z; }",
285 &expect![[r#"
286 Block _id_ [0-12]:
287 Stmt _id_ [2-4]: Semi: Expr _id_ [2-3]: Path: Path _id_ [2-3] (Ident _id_ [2-3] "x")
288 Stmt _id_ [5-7]: Semi: Expr _id_ [5-6]: Path: Path _id_ [5-6] (Ident _id_ [5-6] "y")
289 Stmt _id_ [8-10]: Semi: Expr _id_ [8-9]: Path: Path _id_ [8-9] (Ident _id_ [8-9] "z")"#]],
290 );
291}
292
293#[test]
294fn stmt_missing_semi() {
295 check(
296 parse,
297 "let x = 2",
298 &expect![[r#"
299 Stmt _id_ [0-9]: Local (Immutable):
300 Pat _id_ [4-5]: Bind:
301 Ident _id_ [4-5] "x"
302 Expr _id_ [8-9]: Lit: Int(2)
303
304 [
305 Error(
306 Token(
307 Semi,
308 Eof,
309 Span {
310 lo: 9,
311 hi: 9,
312 },
313 ),
314 ),
315 ]"#]],
316 );
317}
318
319#[test]
320fn if_followed_by() {
321 check(
322 parse_block,
323 "{ if c { x } return x; }",
324 &expect![[r#"
325 Block _id_ [0-24]:
326 Stmt _id_ [2-12]: Expr: Expr _id_ [2-12]: If:
327 Expr _id_ [5-6]: Path: Path _id_ [5-6] (Ident _id_ [5-6] "c")
328 Block _id_ [7-12]:
329 Stmt _id_ [9-10]: Expr: Expr _id_ [9-10]: Path: Path _id_ [9-10] (Ident _id_ [9-10] "x")
330 Stmt _id_ [13-22]: Semi: Expr _id_ [13-21]: Return: Expr _id_ [20-21]: Path: Path _id_ [20-21] (Ident _id_ [20-21] "x")"#]],
331 );
332}
333
334#[test]
335fn let_if() {
336 check(
337 parse_block,
338 "{ let x = if c { true } else { false }; x }",
339 &expect![[r#"
340 Block _id_ [0-43]:
341 Stmt _id_ [2-39]: Local (Immutable):
342 Pat _id_ [6-7]: Bind:
343 Ident _id_ [6-7] "x"
344 Expr _id_ [10-38]: If:
345 Expr _id_ [13-14]: Path: Path _id_ [13-14] (Ident _id_ [13-14] "c")
346 Block _id_ [15-23]:
347 Stmt _id_ [17-21]: Expr: Expr _id_ [17-21]: Lit: Bool(true)
348 Expr _id_ [24-38]: Expr Block: Block _id_ [29-38]:
349 Stmt _id_ [31-36]: Expr: Expr _id_ [31-36]: Lit: Bool(false)
350 Stmt _id_ [40-41]: Expr: Expr _id_ [40-41]: Path: Path _id_ [40-41] (Ident _id_ [40-41] "x")"#]],
351 );
352}
353
354#[test]
355fn empty_block() {
356 check(parse_block, "{}", &expect!["Block _id_ [0-2]: <empty>"]);
357}
358
359#[test]
360fn two_stmts() {
361 check(
362 parse_block,
363 "{ let x = 1; x }",
364 &expect![[r#"
365 Block _id_ [0-16]:
366 Stmt _id_ [2-12]: Local (Immutable):
367 Pat _id_ [6-7]: Bind:
368 Ident _id_ [6-7] "x"
369 Expr _id_ [10-11]: Lit: Int(1)
370 Stmt _id_ [13-14]: Expr: Expr _id_ [13-14]: Path: Path _id_ [13-14] (Ident _id_ [13-14] "x")"#]],
371 );
372}
373
374#[test]
375fn two_empty_stmts() {
376 check(
377 parse_block,
378 "{ ;; }",
379 &expect![[r#"
380 Block _id_ [0-6]:
381 Stmt _id_ [2-3]: Empty
382 Stmt _id_ [3-4]: Empty"#]],
383 );
384}
385
386#[test]
387fn empty_stmt_after_expr() {
388 check(
389 parse_block,
390 "{ x;; }",
391 &expect![[r#"
392 Block _id_ [0-7]:
393 Stmt _id_ [2-4]: Semi: Expr _id_ [2-3]: Path: Path _id_ [2-3] (Ident _id_ [2-3] "x")
394 Stmt _id_ [4-5]: Empty"#]],
395 );
396}
397
398#[test]
399fn call_block_no_parens() {
400 check(
401 parse_block,
402 "{ { let a = b; a }(c, d) }",
403 &expect![[r#"
404 Block _id_ [0-26]:
405 Stmt _id_ [2-18]: Expr: Expr _id_ [2-18]: Expr Block: Block _id_ [2-18]:
406 Stmt _id_ [4-14]: Local (Immutable):
407 Pat _id_ [8-9]: Bind:
408 Ident _id_ [8-9] "a"
409 Expr _id_ [12-13]: Path: Path _id_ [12-13] (Ident _id_ [12-13] "b")
410 Stmt _id_ [15-16]: Expr: Expr _id_ [15-16]: Path: Path _id_ [15-16] (Ident _id_ [15-16] "a")
411 Stmt _id_ [18-24]: Expr: Expr _id_ [18-24]: Tuple:
412 Expr _id_ [19-20]: Path: Path _id_ [19-20] (Ident _id_ [19-20] "c")
413 Expr _id_ [22-23]: Path: Path _id_ [22-23] (Ident _id_ [22-23] "d")"#]],
414 );
415}
416
417#[test]
418fn call_block_parens() {
419 check(
420 parse_block,
421 "{ ({ let a = b; a })(c, d) }",
422 &expect![[r#"
423 Block _id_ [0-28]:
424 Stmt _id_ [2-26]: Expr: Expr _id_ [2-26]: Call:
425 Expr _id_ [2-20]: Paren: Expr _id_ [3-19]: Expr Block: Block _id_ [3-19]:
426 Stmt _id_ [5-15]: Local (Immutable):
427 Pat _id_ [9-10]: Bind:
428 Ident _id_ [9-10] "a"
429 Expr _id_ [13-14]: Path: Path _id_ [13-14] (Ident _id_ [13-14] "b")
430 Stmt _id_ [16-17]: Expr: Expr _id_ [16-17]: Path: Path _id_ [16-17] (Ident _id_ [16-17] "a")
431 Expr _id_ [20-26]: Tuple:
432 Expr _id_ [21-22]: Path: Path _id_ [21-22] (Ident _id_ [21-22] "c")
433 Expr _id_ [24-25]: Path: Path _id_ [24-25] (Ident _id_ [24-25] "d")"#]],
434 );
435}
436
437#[test]
438fn if_stmt_plus() {
439 check(
440 parse_block,
441 "{ if x { 1 } else { 2 } + 3 }",
442 &expect![[r#"
443 Block _id_ [0-29]:
444 Stmt _id_ [2-23]: Expr: Expr _id_ [2-23]: If:
445 Expr _id_ [5-6]: Path: Path _id_ [5-6] (Ident _id_ [5-6] "x")
446 Block _id_ [7-12]:
447 Stmt _id_ [9-10]: Expr: Expr _id_ [9-10]: Lit: Int(1)
448 Expr _id_ [13-23]: Expr Block: Block _id_ [18-23]:
449 Stmt _id_ [20-21]: Expr: Expr _id_ [20-21]: Lit: Int(2)
450 Stmt _id_ [24-27]: Expr: Expr _id_ [24-27]: UnOp (Pos):
451 Expr _id_ [26-27]: Lit: Int(3)"#]],
452 );
453}
454
455#[test]
456fn if_expr_plus() {
457 check(
458 parse_block,
459 "{ let y = if x { 1 } else { 2 } + 3; }",
460 &expect![[r#"
461 Block _id_ [0-38]:
462 Stmt _id_ [2-36]: Local (Immutable):
463 Pat _id_ [6-7]: Bind:
464 Ident _id_ [6-7] "y"
465 Expr _id_ [10-35]: BinOp (Add):
466 Expr _id_ [10-31]: If:
467 Expr _id_ [13-14]: Path: Path _id_ [13-14] (Ident _id_ [13-14] "x")
468 Block _id_ [15-20]:
469 Stmt _id_ [17-18]: Expr: Expr _id_ [17-18]: Lit: Int(1)
470 Expr _id_ [21-31]: Expr Block: Block _id_ [26-31]:
471 Stmt _id_ [28-29]: Expr: Expr _id_ [28-29]: Lit: Int(2)
472 Expr _id_ [34-35]: Lit: Int(3)"#]],
473 );
474}
475
476#[test]
477fn if_semi_if() {
478 check(
479 parse_block,
480 "{ if x { f(); }; if y { g(); } }",
481 &expect![[r#"
482 Block _id_ [0-32]:
483 Stmt _id_ [2-16]: Semi: Expr _id_ [2-15]: If:
484 Expr _id_ [5-6]: Path: Path _id_ [5-6] (Ident _id_ [5-6] "x")
485 Block _id_ [7-15]:
486 Stmt _id_ [9-13]: Semi: Expr _id_ [9-12]: Call:
487 Expr _id_ [9-10]: Path: Path _id_ [9-10] (Ident _id_ [9-10] "f")
488 Expr _id_ [10-12]: Unit
489 Stmt _id_ [17-30]: Expr: Expr _id_ [17-30]: If:
490 Expr _id_ [20-21]: Path: Path _id_ [20-21] (Ident _id_ [20-21] "y")
491 Block _id_ [22-30]:
492 Stmt _id_ [24-28]: Semi: Expr _id_ [24-27]: Call:
493 Expr _id_ [24-25]: Path: Path _id_ [24-25] (Ident _id_ [24-25] "g")
494 Expr _id_ [25-27]: Unit"#]],
495 );
496}
497
498#[test]
499fn if_no_semi_if() {
500 check(
501 parse_block,
502 "{ if x { f(); } if y { g(); } }",
503 &expect![[r#"
504 Block _id_ [0-31]:
505 Stmt _id_ [2-15]: Expr: Expr _id_ [2-15]: If:
506 Expr _id_ [5-6]: Path: Path _id_ [5-6] (Ident _id_ [5-6] "x")
507 Block _id_ [7-15]:
508 Stmt _id_ [9-13]: Semi: Expr _id_ [9-12]: Call:
509 Expr _id_ [9-10]: Path: Path _id_ [9-10] (Ident _id_ [9-10] "f")
510 Expr _id_ [10-12]: Unit
511 Stmt _id_ [16-29]: Expr: Expr _id_ [16-29]: If:
512 Expr _id_ [19-20]: Path: Path _id_ [19-20] (Ident _id_ [19-20] "y")
513 Block _id_ [21-29]:
514 Stmt _id_ [23-27]: Semi: Expr _id_ [23-26]: Call:
515 Expr _id_ [23-24]: Path: Path _id_ [23-24] (Ident _id_ [23-24] "g")
516 Expr _id_ [24-26]: Unit"#]],
517 );
518}
519
520#[test]
521fn call_semi_call() {
522 check(
523 parse_block,
524 "{ f(x); g(y) }",
525 &expect![[r#"
526 Block _id_ [0-14]:
527 Stmt _id_ [2-7]: Semi: Expr _id_ [2-6]: Call:
528 Expr _id_ [2-3]: Path: Path _id_ [2-3] (Ident _id_ [2-3] "f")
529 Expr _id_ [3-6]: Paren: Expr _id_ [4-5]: Path: Path _id_ [4-5] (Ident _id_ [4-5] "x")
530 Stmt _id_ [8-12]: Expr: Expr _id_ [8-12]: Call:
531 Expr _id_ [8-9]: Path: Path _id_ [8-9] (Ident _id_ [8-9] "g")
532 Expr _id_ [9-12]: Paren: Expr _id_ [10-11]: Path: Path _id_ [10-11] (Ident _id_ [10-11] "y")"#]],
533 );
534}
535
536#[test]
537fn call_no_semi_call() {
538 check(
539 parse_block,
540 "{ f(x) g(y) }",
541 &expect![[r#"
542 Block _id_ [0-13]:
543 Stmt _id_ [2-6]: Expr: Expr _id_ [2-6]: Call:
544 Expr _id_ [2-3]: Path: Path _id_ [2-3] (Ident _id_ [2-3] "f")
545 Expr _id_ [3-6]: Paren: Expr _id_ [4-5]: Path: Path _id_ [4-5] (Ident _id_ [4-5] "x")
546 Stmt _id_ [7-11]: Expr: Expr _id_ [7-11]: Call:
547 Expr _id_ [7-8]: Path: Path _id_ [7-8] (Ident _id_ [7-8] "g")
548 Expr _id_ [8-11]: Paren: Expr _id_ [9-10]: Path: Path _id_ [9-10] (Ident _id_ [9-10] "y")
549
550 [
551 Error(
552 MissingSemi(
553 Span {
554 lo: 6,
555 hi: 6,
556 },
557 ),
558 ),
559 ]"#]],
560 );
561}
562
563#[test]
564fn expr_plus_if_semi() {
565 check(
566 parse_block,
567 "{ 1 + if true { 2 } else { 3 }; f(x) }",
568 &expect![[r#"
569 Block _id_ [0-38]:
570 Stmt _id_ [2-31]: Semi: Expr _id_ [2-30]: BinOp (Add):
571 Expr _id_ [2-3]: Lit: Int(1)
572 Expr _id_ [6-30]: If:
573 Expr _id_ [9-13]: Lit: Bool(true)
574 Block _id_ [14-19]:
575 Stmt _id_ [16-17]: Expr: Expr _id_ [16-17]: Lit: Int(2)
576 Expr _id_ [20-30]: Expr Block: Block _id_ [25-30]:
577 Stmt _id_ [27-28]: Expr: Expr _id_ [27-28]: Lit: Int(3)
578 Stmt _id_ [32-36]: Expr: Expr _id_ [32-36]: Call:
579 Expr _id_ [32-33]: Path: Path _id_ [32-33] (Ident _id_ [32-33] "f")
580 Expr _id_ [33-36]: Paren: Expr _id_ [34-35]: Path: Path _id_ [34-35] (Ident _id_ [34-35] "x")"#]],
581 );
582}
583
584#[test]
585fn expr_plus_if_no_semi() {
586 check(
587 parse_block,
588 "{ 1 + if true { 2 } else { 3 } f(x) }",
589 &expect![[r#"
590 Block _id_ [0-37]:
591 Stmt _id_ [2-30]: Expr: Expr _id_ [2-30]: BinOp (Add):
592 Expr _id_ [2-3]: Lit: Int(1)
593 Expr _id_ [6-30]: If:
594 Expr _id_ [9-13]: Lit: Bool(true)
595 Block _id_ [14-19]:
596 Stmt _id_ [16-17]: Expr: Expr _id_ [16-17]: Lit: Int(2)
597 Expr _id_ [20-30]: Expr Block: Block _id_ [25-30]:
598 Stmt _id_ [27-28]: Expr: Expr _id_ [27-28]: Lit: Int(3)
599 Stmt _id_ [31-35]: Expr: Expr _id_ [31-35]: Call:
600 Expr _id_ [31-32]: Path: Path _id_ [31-32] (Ident _id_ [31-32] "f")
601 Expr _id_ [32-35]: Paren: Expr _id_ [33-34]: Path: Path _id_ [33-34] (Ident _id_ [33-34] "x")
602
603 [
604 Error(
605 MissingSemi(
606 Span {
607 lo: 30,
608 hi: 30,
609 },
610 ),
611 ),
612 ]"#]],
613 );
614}
615
616#[test]
617fn block_function() {
618 check(
619 parse_block,
620 "{
621 function Foo() : () {}
622 }",
623 &expect![[r#"
624 Block _id_ [0-46]:
625 Stmt _id_ [14-36]: Item: Item _id_ [14-36]:
626 Callable _id_ [14-36] (Function):
627 name: Ident _id_ [23-26] "Foo"
628 input: Pat _id_ [26-28]: Unit
629 output: Type _id_ [31-33]: Unit
630 body: Block: Block _id_ [34-36]: <empty>"#]],
631 );
632}
633
634#[test]
635fn block_function_doc() {
636 check(
637 parse_block,
638 "{
639 /// This is a doc comment
640 function Foo() : () {}
641 }",
642 &expect![[r#"
643 Block _id_ [0-84]:
644 Stmt _id_ [14-74]: Item: Item _id_ [14-74]:
645 doc:
646 This is a doc comment
647 Callable _id_ [52-74] (Function):
648 name: Ident _id_ [61-64] "Foo"
649 input: Pat _id_ [64-66]: Unit
650 output: Type _id_ [69-71]: Unit
651 body: Block: Block _id_ [72-74]: <empty>"#]],
652 );
653}
654
655#[test]
656fn doc_at_end_of_block() {
657 check(
658 parse_block,
659 "{
660 /// This is a doc comment.
661 }",
662 &expect![[r#"
663 Block _id_ [0-50]:
664 Stmt _id_ [14-40]: Item: Item _id_ [14-40]:
665 Err
666
667 [
668 Error(
669 FloatingDocComment(
670 Span {
671 lo: 14,
672 hi: 40,
673 },
674 ),
675 ),
676 ]"#]],
677 );
678}
679
680#[test]
681fn doc_followed_by_non_item() {
682 check(
683 parse_block,
684 "{
685 /// This is a doc comment
686 let x = 2;
687 }",
688 &expect![[r#"
689 Block _id_ [0-72]:
690 Stmt _id_ [14-39]: Item: Item _id_ [14-39]:
691 Err
692 Stmt _id_ [52-62]: Local (Immutable):
693 Pat _id_ [56-57]: Bind:
694 Ident _id_ [56-57] "x"
695 Expr _id_ [60-61]: Lit: Int(2)
696
697 [
698 Error(
699 FloatingDocComment(
700 Span {
701 lo: 14,
702 hi: 39,
703 },
704 ),
705 ),
706 ]"#]],
707 );
708}
709
710#[test]
711fn recover_in_block() {
712 check(
713 parse_block,
714 "{ let x = 1 +; x }",
715 &expect![[r#"
716 Block _id_ [0-18]:
717 Stmt _id_ [2-14]: Err
718 Stmt _id_ [15-16]: Expr: Expr _id_ [15-16]: Path: Path _id_ [15-16] (Ident _id_ [15-16] "x")
719
720 [
721 Error(
722 Rule(
723 "expression",
724 Semi,
725 Span {
726 lo: 13,
727 hi: 14,
728 },
729 ),
730 ),
731 ]"#]],
732 );
733}
734
735#[test]
736fn recover_in_nested_block() {
737 check(
738 parse_block,
739 "{ let x = { 1 + }; x }",
740 &expect![[r#"
741 Block _id_ [0-22]:
742 Stmt _id_ [2-18]: Local (Immutable):
743 Pat _id_ [6-7]: Bind:
744 Ident _id_ [6-7] "x"
745 Expr _id_ [10-17]: Expr Block: Block _id_ [10-17]:
746 Stmt _id_ [12-15]: Err
747 Stmt _id_ [19-20]: Expr: Expr _id_ [19-20]: Path: Path _id_ [19-20] (Ident _id_ [19-20] "x")
748
749 [
750 Error(
751 Rule(
752 "expression",
753 Close(
754 Brace,
755 ),
756 Span {
757 lo: 16,
758 hi: 17,
759 },
760 ),
761 ),
762 ]"#]],
763 );
764}
765
766#[test]
767fn recover_statements_before_and_after() {
768 check(
769 parse_block,
770 "{
771 let x = 2 + 2;
772 let y = Foo(x
773 let z = x * 3;
774 z
775 }",
776 &expect![[r#"
777 Block _id_ [0-105]:
778 Stmt _id_ [14-28]: Local (Immutable):
779 Pat _id_ [18-19]: Bind:
780 Ident _id_ [18-19] "x"
781 Expr _id_ [22-27]: BinOp (Add):
782 Expr _id_ [22-23]: Lit: Int(2)
783 Expr _id_ [26-27]: Lit: Int(2)
784 Stmt _id_ [41-81]: Err
785 Stmt _id_ [94-95]: Expr: Expr _id_ [94-95]: Path: Path _id_ [94-95] (Ident _id_ [94-95] "z")
786
787 [
788 Error(
789 Token(
790 Close(
791 Paren,
792 ),
793 Keyword(
794 Let,
795 ),
796 Span {
797 lo: 67,
798 hi: 70,
799 },
800 ),
801 ),
802 ]"#]],
803 );
804}
805
806#[test]
807fn recover_missing_semicolon() {
808 check(
809 parse_block,
810 "{
811 let x = 2 + 2;
812 let y = Foo(x)
813 let z = x * 3;
814 z
815 }",
816 &expect![[r#"
817 Block _id_ [0-106]:
818 Stmt _id_ [14-28]: Local (Immutable):
819 Pat _id_ [18-19]: Bind:
820 Ident _id_ [18-19] "x"
821 Expr _id_ [22-27]: BinOp (Add):
822 Expr _id_ [22-23]: Lit: Int(2)
823 Expr _id_ [26-27]: Lit: Int(2)
824 Stmt _id_ [41-55]: Local (Immutable):
825 Pat _id_ [45-46]: Bind:
826 Ident _id_ [45-46] "y"
827 Expr _id_ [49-55]: Call:
828 Expr _id_ [49-52]: Path: Path _id_ [49-52] (Ident _id_ [49-52] "Foo")
829 Expr _id_ [52-55]: Paren: Expr _id_ [53-54]: Path: Path _id_ [53-54] (Ident _id_ [53-54] "x")
830 Stmt _id_ [68-82]: Local (Immutable):
831 Pat _id_ [72-73]: Bind:
832 Ident _id_ [72-73] "z"
833 Expr _id_ [76-81]: BinOp (Mul):
834 Expr _id_ [76-77]: Path: Path _id_ [76-77] (Ident _id_ [76-77] "x")
835 Expr _id_ [80-81]: Lit: Int(3)
836 Stmt _id_ [95-96]: Expr: Expr _id_ [95-96]: Path: Path _id_ [95-96] (Ident _id_ [95-96] "z")
837
838 [
839 Error(
840 Token(
841 Semi,
842 Keyword(
843 Let,
844 ),
845 Span {
846 lo: 68,
847 hi: 71,
848 },
849 ),
850 ),
851 ]"#]],
852 );
853}
854