microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.9.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc_eval/src/tests.rs

4298lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4#![allow(clippy::needless_raw_string_hashes)]
5
6use crate::{
7 backend::{Backend, SparseSim},
8 debug::Frame,
9 exec_graph_section,
10 output::{GenericReceiver, Receiver},
11 val, Env, Error, State, StepAction, StepResult, Value,
12};
13use expect_test::{expect, Expect};
14use indoc::indoc;
15use qsc_data_structures::{language_features::LanguageFeatures, target::TargetCapabilityFlags};
16use qsc_fir::fir::{self, ExecGraph, StmtId};
17use qsc_fir::fir::{PackageId, PackageStoreLookup};
18use qsc_frontend::compile::{self, compile, PackageStore, SourceMap};
19use qsc_lowerer::map_hir_package_to_fir;
20use qsc_passes::{run_core_passes, run_default_passes, PackageType};
21
22/// Evaluates the given control flow graph with the given context.
23/// Creates a new environment and simulator.
24/// # Errors
25/// Returns the first error encountered during execution.
26pub(super) fn eval_graph(
27 graph: ExecGraph,
28 sim: &mut impl Backend<ResultType = impl Into<val::Result>>,
29 globals: &impl PackageStoreLookup,
30 package: PackageId,
31 env: &mut Env,
32 out: &mut impl Receiver,
33) -> Result<Value, (Error, Vec<Frame>)> {
34 let mut state = State::new(package, graph, None);
35 let StepResult::Return(value) =
36 state.eval(globals, env, sim, out, &[], StepAction::Continue)?
37 else {
38 unreachable!("eval_expr should always return a value");
39 };
40 Ok(value)
41}
42
43fn check_expr(file: &str, expr: &str, expect: &Expect) {
44 let mut fir_lowerer = qsc_lowerer::Lowerer::new();
45 let mut core = compile::core();
46 run_core_passes(&mut core);
47 let fir_store = fir::PackageStore::new();
48 // store can be empty since core doesn't have any dependencies
49 let core_fir = fir_lowerer.lower_package(&core.package, &fir_store);
50 let mut store = PackageStore::new(core);
51
52 let mut std = compile::std(&store, TargetCapabilityFlags::all());
53 assert!(std.errors.is_empty());
54 assert!(run_default_passes(store.core(), &mut std, PackageType::Lib).is_empty());
55 let std_fir = fir_lowerer.lower_package(&std.package, &fir_store);
56 let std_id = store.insert(std);
57
58 let sources = SourceMap::new([("test".into(), file.into())], Some(expr.into()));
59 let mut unit = compile(
60 &store,
61 &[(std_id, None)],
62 sources,
63 TargetCapabilityFlags::all(),
64 LanguageFeatures::default(),
65 );
66 assert!(unit.errors.is_empty(), "{:?}", unit.errors);
67 let pass_errors = run_default_passes(store.core(), &mut unit, PackageType::Lib);
68 assert!(pass_errors.is_empty(), "{pass_errors:?}");
69 let unit_fir = fir_lowerer.lower_package(&unit.package, &fir_store);
70 let entry = unit_fir.entry_exec_graph.clone();
71 let id = store.insert(unit);
72
73 let mut fir_store = fir::PackageStore::new();
74 fir_store.insert(
75 map_hir_package_to_fir(qsc_hir::hir::PackageId::CORE),
76 core_fir,
77 );
78 fir_store.insert(map_hir_package_to_fir(std_id), std_fir);
79 fir_store.insert(map_hir_package_to_fir(id), unit_fir);
80
81 let mut out = Vec::new();
82 match eval_graph(
83 entry,
84 &mut SparseSim::new(),
85 &fir_store,
86 map_hir_package_to_fir(id),
87 &mut Env::default(),
88 &mut GenericReceiver::new(&mut out),
89 ) {
90 Ok(value) => expect.assert_eq(&value.to_string()),
91 Err(err) => expect.assert_debug_eq(&err),
92 }
93}
94
95fn check_partial_eval_stmt(
96 file: &str,
97 expr: &str,
98 stmts: &[StmtId],
99 fir_expect: &Expect,
100 result_expect: &Expect,
101) {
102 let mut core = compile::core();
103 run_core_passes(&mut core);
104 let fir_store = fir::PackageStore::new();
105 let core_fir = qsc_lowerer::Lowerer::new().lower_package(&core.package, &fir_store);
106 let mut store = PackageStore::new(core);
107
108 let mut std = compile::std(&store, TargetCapabilityFlags::all());
109 assert!(std.errors.is_empty());
110 assert!(run_default_passes(store.core(), &mut std, PackageType::Lib).is_empty());
111 let std_fir = qsc_lowerer::Lowerer::new().lower_package(&std.package, &fir_store);
112 let std_id = store.insert(std);
113
114 let sources = SourceMap::new([("test".into(), file.into())], Some(expr.into()));
115 let mut unit = compile(
116 &store,
117 &[(std_id, None)],
118 sources,
119 TargetCapabilityFlags::all(),
120 LanguageFeatures::default(),
121 );
122 assert!(unit.errors.is_empty(), "{:?}", unit.errors);
123 let pass_errors = run_default_passes(store.core(), &mut unit, PackageType::Lib);
124 assert!(pass_errors.is_empty(), "{pass_errors:?}");
125 let unit_fir = qsc_lowerer::Lowerer::new().lower_package(&unit.package, &fir_store);
126 fir_expect.assert_eq(&unit_fir.to_string());
127
128 let entry = unit_fir.entry_exec_graph.clone();
129 let id = store.insert(unit);
130
131 let mut fir_store = fir::PackageStore::new();
132 fir_store.insert(
133 map_hir_package_to_fir(qsc_hir::hir::PackageId::CORE),
134 core_fir,
135 );
136 fir_store.insert(map_hir_package_to_fir(std_id), std_fir);
137 let id = map_hir_package_to_fir(id);
138 fir_store.insert(id, unit_fir);
139
140 let mut out = Vec::new();
141 let mut env = Env::default();
142 let (last_stmt, most_stmts) = stmts.split_last().expect("should have at least one stmt");
143 for stmt_id in most_stmts {
144 let stmt = fir_store.get_stmt((id, *stmt_id).into());
145 match eval_graph(
146 exec_graph_section(&entry, stmt.exec_graph_range.clone()),
147 &mut SparseSim::new(),
148 &fir_store,
149 id,
150 &mut env,
151 &mut GenericReceiver::new(&mut out),
152 ) {
153 Ok(_) => {}
154 Err(err) => panic!("Unexpected error: {err:?}"),
155 }
156 }
157
158 let stmt = fir_store.get_stmt((id, *last_stmt).into());
159 match eval_graph(
160 exec_graph_section(&entry, stmt.exec_graph_range.clone()),
161 &mut SparseSim::new(),
162 &fir_store,
163 id,
164 &mut env,
165 &mut GenericReceiver::new(&mut out),
166 ) {
167 Ok(value) => result_expect.assert_eq(&value.to_string()),
168 Err(err) => result_expect.assert_debug_eq(&err),
169 }
170}
171
172#[test]
173fn array_expr() {
174 check_expr("", "[1, 2, 3]", &expect!["[1, 2, 3]"]);
175}
176
177#[test]
178fn array_repeat_expr() {
179 check_expr("", "[4, size = 3]", &expect!["[4, 4, 4]"]);
180}
181
182#[test]
183fn block_expr() {
184 check_expr(
185 "",
186 indoc! { "{
187 let x = 1;
188 let y = x;
189 y
190 }"},
191 &expect!["1"],
192 );
193}
194
195#[test]
196fn block_empty_is_unit_expr() {
197 check_expr("", "{}", &expect!["()"]);
198}
199
200#[test]
201fn block_shadowing_expr() {
202 check_expr(
203 "",
204 indoc! { "{
205 let x = 1;
206 let x = 2;
207 x
208 }"},
209 &expect!["2"],
210 );
211}
212
213#[test]
214fn block_nested_shadowing_expr() {
215 check_expr(
216 "",
217 indoc! { "{
218 let x = 1;
219 let y = {
220 let x = 2;
221 x
222 };
223 (y, x)
224 }"},
225 &expect!["(2, 1)"],
226 );
227}
228
229#[test]
230fn block_let_bind_tuple_expr() {
231 check_expr(
232 "",
233 indoc! {"{
234 let x = (1, 2);
235 let (y, z) = x;
236 (z, y)
237 }"},
238 &expect!["(2, 1)"],
239 );
240}
241
242#[test]
243fn block_mutable_expr() {
244 check_expr(
245 "",
246 indoc! {"{
247 mutable x = 0;
248 x
249 }"},
250 &expect!["0"],
251 );
252}
253
254#[test]
255fn block_mutable_update_expr() {
256 check_expr(
257 "",
258 indoc! {"{
259 mutable x = 0;
260 set x = 1;
261 x
262 }"},
263 &expect!["1"],
264 );
265}
266
267#[test]
268fn block_mutable_update_tuple_expr() {
269 check_expr(
270 "",
271 indoc! {"{
272 mutable x = (0, 1);
273 set x = (1, 2);
274 x
275 }"},
276 &expect!["(1, 2)"],
277 );
278}
279
280#[test]
281fn block_mutable_update_tuple_item_expr() {
282 check_expr(
283 "",
284 indoc! {"{
285 mutable (x, y) = (0, 1);
286 set (x, y) = (1, 2);
287 (x, y)
288 }"},
289 &expect!["(1, 2)"],
290 );
291}
292
293#[test]
294fn block_mutable_update_tuple_hole_expr() {
295 check_expr(
296 "",
297 indoc! {"{
298 mutable (x, y) = (0, 1);
299 set (_, y) = (1, 2);
300 (x, y)
301 }"},
302 &expect!["(0, 2)"],
303 );
304}
305
306#[test]
307fn block_mutable_nested_scopes_expr() {
308 check_expr(
309 "",
310 indoc! {"{
311 mutable x = 0;
312 {
313 mutable y = 1;
314 set x = y;
315 }
316 x
317 }"},
318 &expect!["1"],
319 );
320}
321
322#[test]
323fn block_mutable_nested_scopes_shadowing_expr() {
324 check_expr(
325 "",
326 indoc! {"{
327 mutable x = 0;
328 {
329 mutable x = 1;
330 set x = 2;
331 }
332 x
333 }"},
334 &expect!["0"],
335 );
336}
337
338#[test]
339fn block_qubit_use_expr() {
340 check_expr(
341 "",
342 indoc! {"{
343 use q = Qubit();
344 q
345 }"},
346 &expect!["Qubit0"],
347 );
348}
349
350#[test]
351fn block_qubit_use_use_expr() {
352 check_expr(
353 "",
354 indoc! {"{
355 use q = Qubit();
356 use q1 = Qubit();
357 q1
358 }"},
359 &expect!["Qubit1"],
360 );
361}
362
363#[test]
364fn block_qubit_use_reuse_expr() {
365 check_expr(
366 "",
367 indoc! {"{
368 {
369 use q = Qubit();
370 }
371 use q = Qubit();
372 q
373 }"},
374 &expect!["Qubit0"],
375 );
376}
377
378#[test]
379fn block_qubit_use_scope_reuse_expr() {
380 check_expr(
381 "",
382 indoc! {"{
383 use q = Qubit() {
384 }
385 use q = Qubit();
386 q
387 }"},
388 &expect!["Qubit0"],
389 );
390}
391
392#[test]
393fn block_qubit_use_array_expr() {
394 check_expr(
395 "",
396 indoc! {"{
397 use q = Qubit[3];
398 q
399 }"},
400 &expect!["[Qubit0, Qubit1, Qubit2]"],
401 );
402}
403
404#[test]
405fn block_qubit_use_array_invalid_count_expr() {
406 check_expr(
407 "",
408 indoc! {"{
409 use q = Qubit[-3];
410 q
411 }"},
412 &expect![[r#"
413 (
414 UserFail(
415 "Cannot allocate qubit array with a negative length",
416 PackageSpan {
417 package: PackageId(
418 0,
419 ),
420 span: Span {
421 lo: 2050,
422 hi: 2107,
423 },
424 },
425 ),
426 [
427 Frame {
428 span: Span {
429 lo: 2050,
430 hi: 2107,
431 },
432 id: StoreItemId {
433 package: PackageId(
434 0,
435 ),
436 item: LocalItemId(
437 6,
438 ),
439 },
440 caller: PackageId(
441 2,
442 ),
443 functor: FunctorApp {
444 adjoint: false,
445 controlled: 0,
446 },
447 },
448 ],
449 )
450 "#]],
451 );
452}
453
454#[test]
455fn block_qubit_use_tuple_expr() {
456 check_expr(
457 "",
458 indoc! {"{
459 use q = (Qubit[3], Qubit(), Qubit());
460 q
461 }"},
462 &expect!["([Qubit0, Qubit1, Qubit2], Qubit3, Qubit4)"],
463 );
464}
465
466#[test]
467fn block_qubit_use_nested_tuple_expr() {
468 check_expr(
469 "",
470 indoc! {"{
471 use q = (Qubit[3], (Qubit(), Qubit()));
472 q
473 }"},
474 &expect!["([Qubit0, Qubit1, Qubit2], (Qubit3, Qubit4))"],
475 );
476}
477
478#[test]
479fn block_with_no_stmts_is_unit() {
480 check_expr("", "{}", &expect!["()"]);
481}
482
483#[test]
484fn block_with_semi_is_unit() {
485 check_expr("", "{4;}", &expect!["()"]);
486}
487
488#[test]
489fn binop_add_array() {
490 check_expr("", "[1, 2] + [3, 4]", &expect!["[1, 2, 3, 4]"]);
491}
492
493#[test]
494fn binop_add_bigint() {
495 check_expr(
496 "",
497 "2L + 9_223_372_036_854_775_808L",
498 &expect!["9223372036854775810"],
499 );
500}
501
502#[test]
503fn binop_add_double() {
504 check_expr("", "2.8 + 5.4", &expect!["8.2"]);
505}
506
507#[test]
508fn binop_add_int() {
509 check_expr("", "28 + 54", &expect!["82"]);
510}
511
512#[test]
513fn binop_add_int_wrap() {
514 check_expr(
515 "",
516 "0x7FFFFFFFFFFFFFFF + 1",
517 &expect!["-9223372036854775808"],
518 );
519}
520
521#[test]
522fn binop_add_string() {
523 check_expr("", r#""Hello," + " World!""#, &expect!["Hello, World!"]);
524}
525
526#[test]
527fn binop_andb_bigint() {
528 check_expr("", "28L &&& 54L", &expect!["20"]);
529}
530
531#[test]
532fn binop_andb_int() {
533 check_expr("", "28 &&& 54", &expect!["20"]);
534}
535
536#[test]
537fn binop_andl() {
538 check_expr("", "true and true", &expect!["true"]);
539}
540
541#[test]
542fn binop_andl_false() {
543 check_expr("", "true and false", &expect!["false"]);
544}
545
546#[test]
547fn binop_andl_shortcut() {
548 check_expr("", r#"false and (fail "Should Fail")"#, &expect!["false"]);
549}
550
551#[test]
552fn binop_andl_no_shortcut() {
553 check_expr(
554 "",
555 r#"true and (fail "Should Fail")"#,
556 &expect![[r#"
557 (
558 UserFail(
559 "Should Fail",
560 PackageSpan {
561 package: PackageId(
562 2,
563 ),
564 span: Span {
565 lo: 10,
566 hi: 28,
567 },
568 },
569 ),
570 [],
571 )
572 "#]],
573 );
574}
575
576#[test]
577fn binop_div_bigint() {
578 check_expr("", "12L / 3L", &expect!["4"]);
579}
580
581#[test]
582fn binop_div_bigint_zero() {
583 check_expr(
584 "",
585 "12L / 0L",
586 &expect![[r#"
587 (
588 DivZero(
589 PackageSpan {
590 package: PackageId(
591 2,
592 ),
593 span: Span {
594 lo: 6,
595 hi: 8,
596 },
597 },
598 ),
599 [],
600 )
601 "#]],
602 );
603}
604
605#[test]
606fn binop_div_int() {
607 check_expr("", "12 / 3", &expect!["4"]);
608}
609
610#[test]
611fn binop_div_int_wrap() {
612 check_expr(
613 "",
614 "(-0x8000000000000000) / (-1)",
615 &expect!["-9223372036854775808"],
616 );
617}
618
619#[test]
620fn binop_div_int_zero() {
621 check_expr(
622 "",
623 "12 / 0",
624 &expect![[r#"
625 (
626 DivZero(
627 PackageSpan {
628 package: PackageId(
629 2,
630 ),
631 span: Span {
632 lo: 5,
633 hi: 6,
634 },
635 },
636 ),
637 [],
638 )
639 "#]],
640 );
641}
642
643#[test]
644fn binop_div_double() {
645 check_expr("", "1.2 / 0.3", &expect!["4.0"]);
646}
647
648#[test]
649fn binop_div_double_inf() {
650 check_expr("", "1.2 / 0.0", &expect!["inf"]);
651}
652
653#[test]
654fn binop_div_double_neg_inf() {
655 check_expr("", "1.2 / -0.0", &expect!["-inf"]);
656}
657
658#[test]
659fn binop_div_double_nan() {
660 check_expr("", "0.0 / 0.0", &expect!["NaN"]);
661}
662
663#[test]
664fn binop_eq_double() {
665 check_expr("", "1.2 / 0.3", &expect!["4.0"]);
666}
667
668#[test]
669fn binop_equal_array() {
670 check_expr("", "[1, 2, 3] == [1, 2, 3]", &expect!["true"]);
671}
672
673#[test]
674fn binop_equal_array_false_content() {
675 check_expr("", "[1, 2, 3] == [1, 0, 3]", &expect!["false"]);
676}
677
678#[test]
679fn binop_equal_array_false_length() {
680 check_expr("", "[1, 2, 3] == [1, 2, 3, 4]", &expect!["false"]);
681}
682
683#[test]
684fn binop_equal_bigint() {
685 check_expr("", "18L == 18L", &expect!["true"]);
686}
687
688#[test]
689fn binop_equal_bigint_false() {
690 check_expr("", "18L == 8L", &expect!["false"]);
691}
692
693#[test]
694fn binop_equal_bool() {
695 check_expr("", "false == false", &expect!["true"]);
696}
697
698#[test]
699fn binop_equal_bool_false() {
700 check_expr("", "false == true", &expect!["false"]);
701}
702
703#[test]
704fn binop_equal_double() {
705 check_expr("", "1.254 == 1.254", &expect!["true"]);
706}
707
708#[test]
709fn binop_equal_double_false() {
710 check_expr("", "1.254 == 1.25", &expect!["false"]);
711}
712
713#[test]
714fn binop_equal_int() {
715 check_expr("", "42 == 42", &expect!["true"]);
716}
717
718#[test]
719fn binop_equal_int_false() {
720 check_expr("", "42 == 43", &expect!["false"]);
721}
722
723#[test]
724fn binop_equal_pauli() {
725 check_expr("", "PauliX == PauliX", &expect!["true"]);
726}
727
728#[test]
729fn binop_equal_pauli_false() {
730 check_expr("", "PauliX == PauliZ", &expect!["false"]);
731}
732
733#[test]
734fn binop_equal_range() {
735 check_expr("", "(0..4) == (0..4)", &expect!["true"]);
736}
737
738#[test]
739fn binop_equal_range_false() {
740 check_expr("", "(0..2..4) == (0..4)", &expect!["false"]);
741}
742
743#[test]
744fn binop_equal_result() {
745 check_expr("", "One == One", &expect!["true"]);
746}
747
748#[test]
749fn binop_equal_result_false() {
750 check_expr("", "One == Zero", &expect!["false"]);
751}
752
753#[test]
754fn binop_equal_string() {
755 check_expr("", r#""foo" == "foo""#, &expect!["true"]);
756}
757
758#[test]
759fn binop_equal_string_false() {
760 check_expr("", r#""foo" == "bar""#, &expect!["false"]);
761}
762
763#[test]
764fn binop_equal_tuple() {
765 check_expr("", "(1, 2, 3) == (1, 2, 3)", &expect!["true"]);
766}
767
768#[test]
769fn binop_equal_tuple_false_content() {
770 check_expr("", "(1, 2, 3) == (1, -2, 3)", &expect!["false"]);
771}
772
773#[test]
774fn binop_exp_bigint() {
775 check_expr("", "2L^3", &expect!["8"]);
776}
777
778#[test]
779fn binop_exp_bigint_zero_exp() {
780 check_expr("", "2L^0", &expect!["1"]);
781}
782
783#[test]
784fn binop_exp_bigint_neg_zero_exp() {
785 check_expr("", "(-2L)^0", &expect!["1"]);
786}
787
788#[test]
789fn binop_exp_bigint_negative_exp() {
790 check_expr(
791 "",
792 "2L^-3",
793 &expect![[r#"
794 (
795 InvalidNegativeInt(
796 -3,
797 PackageSpan {
798 package: PackageId(
799 2,
800 ),
801 span: Span {
802 lo: 3,
803 hi: 5,
804 },
805 },
806 ),
807 [],
808 )
809 "#]],
810 );
811}
812
813#[test]
814fn binop_exp_bigint_too_large() {
815 check_expr(
816 "",
817 "2L^9_223_372_036_854_775_807",
818 &expect![[r#"
819 (
820 IntTooLarge(
821 9223372036854775807,
822 PackageSpan {
823 package: PackageId(
824 2,
825 ),
826 span: Span {
827 lo: 3,
828 hi: 28,
829 },
830 },
831 ),
832 [],
833 )
834 "#]],
835 );
836}
837
838#[test]
839fn binop_exp_double() {
840 check_expr("", "2.3^3.1", &expect!["13.22380059125472"]);
841}
842
843#[test]
844fn binop_exp_double_negative_exp() {
845 check_expr("", "2.3^-3.1", &expect!["0.07562122501010253"]);
846}
847
848#[test]
849fn binop_exp_int() {
850 check_expr("", "2^3", &expect!["8"]);
851}
852
853#[test]
854fn binop_exp_int_zero_exp() {
855 check_expr("", "2^0", &expect!["1"]);
856}
857
858#[test]
859fn binop_exp_int_neg_zero_exp() {
860 check_expr("", "(-2)^0", &expect!["1"]);
861}
862
863#[test]
864fn binop_exp_int_negative_exp() {
865 check_expr(
866 "",
867 "2^-3",
868 &expect![[r#"
869 (
870 InvalidNegativeInt(
871 -3,
872 PackageSpan {
873 package: PackageId(
874 2,
875 ),
876 span: Span {
877 lo: 2,
878 hi: 4,
879 },
880 },
881 ),
882 [],
883 )
884 "#]],
885 );
886}
887
888#[test]
889fn binop_exp_int_too_large() {
890 check_expr(
891 "",
892 "100^50",
893 &expect![[r#"
894 (
895 IntTooLarge(
896 50,
897 PackageSpan {
898 package: PackageId(
899 2,
900 ),
901 span: Span {
902 lo: 4,
903 hi: 6,
904 },
905 },
906 ),
907 [],
908 )
909 "#]],
910 );
911}
912
913#[test]
914fn binop_gt_bigint() {
915 check_expr("", "23L > 3L", &expect!["true"]);
916}
917
918#[test]
919fn binop_gt_bigint_false() {
920 check_expr("", "2L > 3L", &expect!["false"]);
921}
922
923#[test]
924fn binop_gt_int() {
925 check_expr("", "23 > 3", &expect!["true"]);
926}
927
928#[test]
929fn binop_gt_int_false() {
930 check_expr("", "2 > 3", &expect!["false"]);
931}
932
933#[test]
934fn binop_gt_double() {
935 check_expr("", "2.3 > 0.3", &expect!["true"]);
936}
937
938#[test]
939fn binop_gt_double_false() {
940 check_expr("", "0.2 > 0.3", &expect!["false"]);
941}
942
943#[test]
944fn binop_gte_bigint() {
945 check_expr("", "23L >= 3L", &expect!["true"]);
946}
947
948#[test]
949fn binop_gte_bigint_false() {
950 check_expr("", "2L >= 3L", &expect!["false"]);
951}
952
953#[test]
954fn binop_gte_bigint_eq() {
955 check_expr("", "3L >= 3L", &expect!["true"]);
956}
957
958#[test]
959fn binop_gte_int() {
960 check_expr("", "23 >= 3", &expect!["true"]);
961}
962
963#[test]
964fn binop_gte_int_false() {
965 check_expr("", "2 >= 3", &expect!["false"]);
966}
967
968#[test]
969fn binop_gte_int_eq() {
970 check_expr("", "3 >= 3", &expect!["true"]);
971}
972
973#[test]
974fn binop_gte_double() {
975 check_expr("", "2.3 >= 0.3", &expect!["true"]);
976}
977
978#[test]
979fn binop_gte_double_false() {
980 check_expr("", "0.2 >= 0.3", &expect!["false"]);
981}
982
983#[test]
984fn binop_gte_double_eq() {
985 check_expr("", "0.3 >= 0.3", &expect!["true"]);
986}
987
988#[test]
989fn binop_lt_bigint_false() {
990 check_expr("", "23L < 3L", &expect!["false"]);
991}
992
993#[test]
994fn binop_lt_bigint() {
995 check_expr("", "2L < 3L", &expect!["true"]);
996}
997
998#[test]
999fn binop_lt_int_false() {
1000 check_expr("", "23 < 3", &expect!["false"]);
1001}
1002
1003#[test]
1004fn binop_lt_int() {
1005 check_expr("", "2 < 3", &expect!["true"]);
1006}
1007
1008#[test]
1009fn binop_lt_double_false() {
1010 check_expr("", "2.3 < 0.3", &expect!["false"]);
1011}
1012
1013#[test]
1014fn binop_lt_double() {
1015 check_expr("", "0.2 < 0.3", &expect!["true"]);
1016}
1017
1018#[test]
1019fn binop_lte_bigint_false() {
1020 check_expr("", "23L <= 3L", &expect!["false"]);
1021}
1022
1023#[test]
1024fn binop_lte_bigint() {
1025 check_expr("", "2L <= 3L", &expect!["true"]);
1026}
1027
1028#[test]
1029fn binop_lte_bigint_eq() {
1030 check_expr("", "3L <= 3L", &expect!["true"]);
1031}
1032
1033#[test]
1034fn binop_lte_int_false() {
1035 check_expr("", "23 <= 3", &expect!["false"]);
1036}
1037
1038#[test]
1039fn binop_lte_int() {
1040 check_expr("", "2 <= 3", &expect!["true"]);
1041}
1042
1043#[test]
1044fn binop_lte_int_eq() {
1045 check_expr("", "3 <= 3", &expect!["true"]);
1046}
1047
1048#[test]
1049fn binop_lte_double_false() {
1050 check_expr("", "2.3 <= 0.3", &expect!["false"]);
1051}
1052
1053#[test]
1054fn binop_lte_double() {
1055 check_expr("", "0.2 <= 0.3", &expect!["true"]);
1056}
1057
1058#[test]
1059fn binop_lte_double_eq() {
1060 check_expr("", "0.3 <= 0.3", &expect!["true"]);
1061}
1062
1063#[test]
1064fn binop_mod_bigint() {
1065 check_expr("", "8L % 6L", &expect!["2"]);
1066}
1067
1068#[test]
1069fn binop_mod_bigint_zero() {
1070 check_expr(
1071 "",
1072 "12L % 0L",
1073 &expect![[r#"
1074 (
1075 DivZero(
1076 PackageSpan {
1077 package: PackageId(
1078 2,
1079 ),
1080 span: Span {
1081 lo: 6,
1082 hi: 8,
1083 },
1084 },
1085 ),
1086 [],
1087 )
1088 "#]],
1089 );
1090}
1091
1092#[test]
1093fn binop_mod_int() {
1094 check_expr("", "8 % 6", &expect!["2"]);
1095}
1096
1097#[test]
1098fn binop_mod_int_wrap() {
1099 check_expr("", "(-0x8000000000000000) % (-1)", &expect!["0"]);
1100}
1101
1102#[test]
1103fn binop_mod_int_zero() {
1104 check_expr(
1105 "",
1106 "12 % 0",
1107 &expect![[r#"
1108 (
1109 DivZero(
1110 PackageSpan {
1111 package: PackageId(
1112 2,
1113 ),
1114 span: Span {
1115 lo: 5,
1116 hi: 6,
1117 },
1118 },
1119 ),
1120 [],
1121 )
1122 "#]],
1123 );
1124}
1125
1126#[test]
1127fn binop_mod_double() {
1128 check_expr("", "8.411 % 6.833", &expect!["1.5779999999999994"]);
1129}
1130
1131#[test]
1132fn binop_mod_double_zero() {
1133 check_expr(
1134 "",
1135 "1.2 % 0.0",
1136 &expect![[r#"
1137 (
1138 DivZero(
1139 PackageSpan {
1140 package: PackageId(
1141 2,
1142 ),
1143 span: Span {
1144 lo: 6,
1145 hi: 9,
1146 },
1147 },
1148 ),
1149 [],
1150 )
1151 "#]],
1152 );
1153}
1154
1155#[test]
1156fn binop_mul_bigint() {
1157 check_expr("", "8L * 6L", &expect!["48"]);
1158}
1159
1160#[test]
1161fn binop_mul_int() {
1162 check_expr("", "8 * 6", &expect!["48"]);
1163}
1164#[test]
1165fn binop_mul_int_wrap() {
1166 check_expr(
1167 "",
1168 "0x7FFFFFFFFFFFFFFF * 0xFF",
1169 &expect!["9223372036854775553"],
1170 );
1171}
1172
1173#[test]
1174fn binop_mul_double() {
1175 check_expr("", "8.411 * 6.833", &expect!["57.472363"]);
1176}
1177
1178#[test]
1179fn binop_neq_array() {
1180 check_expr("", "[1, 2, 3] != [1, 2, 3]", &expect!["false"]);
1181}
1182
1183#[test]
1184fn binop_neq_array_true_content() {
1185 check_expr("", "[1, 2, 3] != [1, 0, 3]", &expect!["true"]);
1186}
1187
1188#[test]
1189fn binop_neq_array_true_length() {
1190 check_expr("", "[1, 2, 3] != [1, 2, 3, 4]", &expect!["true"]);
1191}
1192
1193#[test]
1194fn binop_neq_bigint() {
1195 check_expr("", "18L != 18L", &expect!["false"]);
1196}
1197
1198#[test]
1199fn binop_neq_bigint_true() {
1200 check_expr("", "18L != 8L", &expect!["true"]);
1201}
1202
1203#[test]
1204fn binop_neq_bool() {
1205 check_expr("", "false != false", &expect!["false"]);
1206}
1207
1208#[test]
1209fn binop_neq_bool_true() {
1210 check_expr("", "false != true", &expect!["true"]);
1211}
1212
1213#[test]
1214fn binop_neq_double() {
1215 check_expr("", "1.254 != 1.254", &expect!["false"]);
1216}
1217
1218#[test]
1219fn binop_neq_double_true() {
1220 check_expr("", "1.254 != 1.25", &expect!["true"]);
1221}
1222
1223#[test]
1224fn binop_neq_int() {
1225 check_expr("", "42 != 42", &expect!["false"]);
1226}
1227
1228#[test]
1229fn binop_neq_int_true() {
1230 check_expr("", "42 != 43", &expect!["true"]);
1231}
1232
1233#[test]
1234fn binop_neq_pauli() {
1235 check_expr("", "PauliX != PauliX", &expect!["false"]);
1236}
1237
1238#[test]
1239fn binop_neq_pauli_true() {
1240 check_expr("", "PauliX != PauliZ", &expect!["true"]);
1241}
1242
1243#[test]
1244fn binop_neq_range() {
1245 check_expr("", "(0..4) != (0..4)", &expect!["false"]);
1246}
1247
1248#[test]
1249fn binop_neq_range_true() {
1250 check_expr("", "(0..2..4) != (0..4)", &expect!["true"]);
1251}
1252
1253#[test]
1254fn binop_neq_result() {
1255 check_expr("", "One != One", &expect!["false"]);
1256}
1257
1258#[test]
1259fn binop_neq_result_true() {
1260 check_expr("", "One != Zero", &expect!["true"]);
1261}
1262
1263#[test]
1264fn binop_neq_string() {
1265 check_expr("", r#""foo" != "foo""#, &expect!["false"]);
1266}
1267
1268#[test]
1269fn binop_neq_string_true() {
1270 check_expr("", r#""foo" != "bar""#, &expect!["true"]);
1271}
1272
1273#[test]
1274fn binop_neq_tuple() {
1275 check_expr("", "(1, 2, 3) != (1, 2, 3)", &expect!["false"]);
1276}
1277
1278#[test]
1279fn binop_neq_tuple_true_content() {
1280 check_expr("", "(1, 2, 3) != (1, -2, 3)", &expect!["true"]);
1281}
1282
1283#[test]
1284fn binop_orb_bigint() {
1285 check_expr("", "28L ||| 54L", &expect!["62"]);
1286}
1287
1288#[test]
1289fn binop_orb_int() {
1290 check_expr("", "28 ||| 54", &expect!["62"]);
1291}
1292
1293#[test]
1294fn binop_orl() {
1295 check_expr("", "true or true", &expect!["true"]);
1296}
1297
1298#[test]
1299fn binop_orl_true_lhs() {
1300 check_expr("", "true or false", &expect!["true"]);
1301}
1302
1303#[test]
1304fn binop_orl_true_rhs() {
1305 check_expr("", "false or true", &expect!["true"]);
1306}
1307
1308#[test]
1309fn binop_orl_false() {
1310 check_expr("", "false or false", &expect!["false"]);
1311}
1312
1313#[test]
1314fn binop_orl_shortcut() {
1315 check_expr("", r#"true or (fail "Shouldn't Fail")"#, &expect!["true"]);
1316}
1317
1318#[test]
1319fn binop_shl_bigint() {
1320 check_expr("", "4L <<< 2", &expect!["16"]);
1321}
1322
1323#[test]
1324fn binop_shl_bigint_negative() {
1325 check_expr("", "4L <<< -2", &expect!["1"]);
1326}
1327
1328#[test]
1329fn binop_shl_int() {
1330 check_expr("", "4 <<< 2", &expect!["16"]);
1331}
1332
1333#[test]
1334fn binop_shl_int_negative() {
1335 check_expr("", "4 <<< -2", &expect!["1"]);
1336}
1337
1338#[test]
1339fn binop_shl_int_truncate() {
1340 check_expr("", "1 <<< 63", &expect!["-9223372036854775808"]);
1341 check_expr("", "2 <<< 63", &expect!["0"]);
1342}
1343
1344#[test]
1345fn binop_shl_int_overflow() {
1346 check_expr(
1347 "",
1348 "1 <<< 64",
1349 &expect![[r#"
1350 (
1351 IntTooLarge(
1352 64,
1353 PackageSpan {
1354 package: PackageId(
1355 2,
1356 ),
1357 span: Span {
1358 lo: 6,
1359 hi: 8,
1360 },
1361 },
1362 ),
1363 [],
1364 )
1365 "#]],
1366 );
1367}
1368
1369#[test]
1370fn binop_shr_bigint() {
1371 check_expr("", "4L >>> 2", &expect!["1"]);
1372}
1373
1374#[test]
1375fn binop_shr_bigint_negative() {
1376 check_expr("", "4L >>> -2", &expect!["16"]);
1377}
1378
1379#[test]
1380fn binop_shr_int() {
1381 check_expr("", "4 >>> 2", &expect!["1"]);
1382}
1383
1384#[test]
1385fn binop_shr_int_negative() {
1386 check_expr("", "4 >>> -2", &expect!["16"]);
1387}
1388
1389#[test]
1390fn binop_shr_int_truncate() {
1391 check_expr("", "(-9223372036854775808) >>> 63", &expect!["-1"]);
1392 check_expr("", "1 >>> 63", &expect!["0"]);
1393}
1394
1395#[test]
1396fn binop_shr_int_overflow() {
1397 check_expr(
1398 "",
1399 "1 >>> 64",
1400 &expect![[r#"
1401 (
1402 IntTooLarge(
1403 64,
1404 PackageSpan {
1405 package: PackageId(
1406 2,
1407 ),
1408 span: Span {
1409 lo: 6,
1410 hi: 8,
1411 },
1412 },
1413 ),
1414 [],
1415 )
1416 "#]],
1417 );
1418}
1419
1420#[test]
1421fn binop_sub_bigint() {
1422 check_expr("", "4L - 2L", &expect!["2"]);
1423}
1424
1425#[test]
1426fn binop_sub_int() {
1427 check_expr("", "4 - 2", &expect!["2"]);
1428}
1429
1430#[test]
1431fn binop_sub_int_wrap() {
1432 check_expr(
1433 "",
1434 "-0x8000000000000000 - 1",
1435 &expect!["9223372036854775807"],
1436 );
1437}
1438
1439#[test]
1440fn binop_sub_double() {
1441 check_expr("", "4.7 - 2.5", &expect!["2.2"]);
1442}
1443
1444#[test]
1445fn binop_xorb_bigint() {
1446 check_expr("", "28L ^^^ 54L", &expect!["42"]);
1447}
1448
1449#[test]
1450fn binop_xorb_int() {
1451 check_expr("", "28 ^^^ 54", &expect!["42"]);
1452}
1453
1454#[test]
1455fn assignop_add_expr() {
1456 check_expr(
1457 "",
1458 indoc! {"{
1459 mutable x = 0;
1460 set x += 1;
1461 x
1462 }"},
1463 &expect!["1"],
1464 );
1465}
1466
1467#[test]
1468fn assignop_add_concat() {
1469 check_expr(
1470 "",
1471 indoc! {"{
1472 mutable x = [1, 2];
1473 set x += [3, 4];
1474 x
1475 }"},
1476 &expect!["[1, 2, 3, 4]"],
1477 );
1478}
1479
1480#[test]
1481fn assignop_add_concat_copy() {
1482 check_expr(
1483 "",
1484 indoc! {"{
1485 let x = [1, 2];
1486 mutable y = x;
1487 set y += [3, 4];
1488 (x, y)
1489 }"},
1490 &expect!["([1, 2], [1, 2, 3, 4])"],
1491 );
1492}
1493
1494#[test]
1495fn assignop_sub_expr() {
1496 check_expr(
1497 "",
1498 indoc! {"{
1499 mutable x = 0;
1500 set x -= 1;
1501 x
1502 }"},
1503 &expect!["-1"],
1504 );
1505}
1506
1507#[test]
1508fn assignop_orl_expr() {
1509 check_expr(
1510 "",
1511 indoc! {"{
1512 mutable x = false;
1513 set x or= true;
1514 x
1515 }"},
1516 &expect!["true"],
1517 );
1518}
1519
1520#[test]
1521fn fail_expr() {
1522 check_expr(
1523 "",
1524 r#"fail "This is a failure""#,
1525 &expect![[r#"
1526 (
1527 UserFail(
1528 "This is a failure",
1529 PackageSpan {
1530 package: PackageId(
1531 2,
1532 ),
1533 span: Span {
1534 lo: 0,
1535 hi: 24,
1536 },
1537 },
1538 ),
1539 [],
1540 )
1541 "#]],
1542 );
1543}
1544
1545#[test]
1546fn fail_shortcut_expr() {
1547 check_expr(
1548 "",
1549 r#"{ fail "Got Here!"; fail "Shouldn't get here..."; }"#,
1550 &expect![[r#"
1551 (
1552 UserFail(
1553 "Got Here!",
1554 PackageSpan {
1555 package: PackageId(
1556 2,
1557 ),
1558 span: Span {
1559 lo: 2,
1560 hi: 18,
1561 },
1562 },
1563 ),
1564 [],
1565 )
1566 "#]],
1567 );
1568}
1569
1570#[test]
1571fn field_range_start_expr() {
1572 check_expr("", "(0..2..8)::Start", &expect!["0"]);
1573}
1574
1575#[test]
1576fn field_range_step_expr() {
1577 check_expr("", "(0..2..8)::Step", &expect!["2"]);
1578}
1579
1580#[test]
1581fn field_range_step_missing_treated_as_1_expr() {
1582 check_expr("", "(0..8)::Step", &expect!["1"]);
1583}
1584
1585#[test]
1586fn field_range_end_expr() {
1587 check_expr("", "(0..2..8)::End", &expect!["8"]);
1588}
1589
1590#[test]
1591fn for_loop_range_expr() {
1592 check_expr(
1593 "",
1594 indoc! {"{
1595 mutable x = 0;
1596 for i in 0..10 {
1597 set x = x + i;
1598 }
1599 x
1600 }"},
1601 &expect!["55"],
1602 );
1603}
1604
1605#[test]
1606fn for_loop_array_expr() {
1607 check_expr(
1608 "",
1609 indoc! {"{
1610 mutable x = 0;
1611 for i in [5, size = 5] {
1612 set x = x + i;
1613 }
1614 x
1615 }"},
1616 &expect!["25"],
1617 );
1618}
1619
1620#[test]
1621fn for_loop_ignore_iterator_expr() {
1622 check_expr(
1623 "",
1624 indoc! {"{
1625 mutable x = 0;
1626 for _ in [5, size = 5] {
1627 set x = x + 1;
1628 }
1629 x
1630 }"},
1631 &expect!["5"],
1632 );
1633}
1634
1635#[test]
1636fn array_index_expr() {
1637 check_expr("", "[1, 2, 3][1]", &expect!["2"]);
1638}
1639
1640#[test]
1641fn array_slice_start_end_expr() {
1642 check_expr("", "[1, 2, 3, 4, 5][0..2]", &expect!["[1, 2, 3]"]);
1643}
1644
1645#[test]
1646fn array_slice_start_step_end_expr() {
1647 check_expr("", "[1, 2, 3, 4, 5][0..2..2]", &expect!["[1, 3]"]);
1648}
1649
1650#[test]
1651fn array_slice_start_expr() {
1652 check_expr("", "[1, 2, 3, 4, 5][2...]", &expect!["[3, 4, 5]"]);
1653}
1654
1655#[test]
1656fn array_slice_end_expr() {
1657 check_expr("", "[1, 2, 3, 4, 5][...2]", &expect!["[1, 2, 3]"]);
1658}
1659
1660#[test]
1661fn array_slice_step_end_expr() {
1662 check_expr("", "[1, 2, 3, 4, 5][...2..3]", &expect!["[1, 3]"]);
1663}
1664
1665#[test]
1666fn array_slice_step_expr() {
1667 check_expr("", "[1, 2, 3, 4, 5][...2...]", &expect!["[1, 3, 5]"]);
1668}
1669
1670#[test]
1671fn array_slice_reverse_expr() {
1672 check_expr("", "[1, 2, 3, 4, 5][2..-1..0]", &expect!["[3, 2, 1]"]);
1673}
1674
1675#[test]
1676fn array_slice_reverse_end_expr() {
1677 check_expr("", "[1, 2, 3, 4, 5][...-1..2]", &expect!["[5, 4, 3]"]);
1678}
1679
1680#[test]
1681fn array_slice_reverse_start_expr() {
1682 check_expr("", "[1, 2, 3, 4, 5][2..-1...]", &expect!["[3, 2, 1]"]);
1683}
1684
1685#[test]
1686fn array_slice_reverse_all_expr() {
1687 check_expr("", "[1, 2, 3, 4, 5][...-1...]", &expect!["[5, 4, 3, 2, 1]"]);
1688}
1689
1690#[test]
1691fn array_slice_all_expr() {
1692 check_expr("", "[1, 2, 3, 4, 5][...]", &expect!["[1, 2, 3, 4, 5]"]);
1693}
1694
1695#[test]
1696fn array_slice_none_expr() {
1697 check_expr("", "[1, 2, 3, 4, 5][1..0]", &expect!["[]"]);
1698}
1699
1700#[test]
1701fn array_slice_reverse_none_expr() {
1702 check_expr("", "[1, 2, 3, 4, 5][0..-1..1]", &expect!["[]"]);
1703}
1704
1705#[test]
1706fn array_slice_step_zero_expr() {
1707 check_expr(
1708 "",
1709 "[1, 2, 3, 4, 5][...0...]",
1710 &expect![[r#"
1711 (
1712 RangeStepZero(
1713 PackageSpan {
1714 package: PackageId(
1715 2,
1716 ),
1717 span: Span {
1718 lo: 16,
1719 hi: 23,
1720 },
1721 },
1722 ),
1723 [],
1724 )
1725 "#]],
1726 );
1727}
1728
1729#[test]
1730fn array_slice_out_of_range_expr() {
1731 check_expr(
1732 "",
1733 "[1, 2, 3, 4, 5][0..7]",
1734 &expect![[r#"
1735 (
1736 IndexOutOfRange(
1737 5,
1738 PackageSpan {
1739 package: PackageId(
1740 2,
1741 ),
1742 span: Span {
1743 lo: 16,
1744 hi: 20,
1745 },
1746 },
1747 ),
1748 [],
1749 )
1750 "#]],
1751 );
1752}
1753
1754#[test]
1755fn array_index_negative_expr() {
1756 check_expr(
1757 "",
1758 "[1, 2, 3][-2]",
1759 &expect![[r#"
1760 (
1761 InvalidIndex(
1762 -2,
1763 PackageSpan {
1764 package: PackageId(
1765 2,
1766 ),
1767 span: Span {
1768 lo: 10,
1769 hi: 12,
1770 },
1771 },
1772 ),
1773 [],
1774 )
1775 "#]],
1776 );
1777}
1778
1779#[test]
1780fn array_index_out_of_range_expr() {
1781 check_expr(
1782 "",
1783 "[1, 2, 3][4]",
1784 &expect![[r#"
1785 (
1786 IndexOutOfRange(
1787 4,
1788 PackageSpan {
1789 package: PackageId(
1790 2,
1791 ),
1792 span: Span {
1793 lo: 10,
1794 hi: 11,
1795 },
1796 },
1797 ),
1798 [],
1799 )
1800 "#]],
1801 );
1802}
1803
1804#[test]
1805fn literal_big_int_expr() {
1806 check_expr(
1807 "",
1808 "9_223_372_036_854_775_808L",
1809 &expect!["9223372036854775808"],
1810 );
1811}
1812
1813#[test]
1814fn literal_bool_false_expr() {
1815 check_expr("", "false", &expect!["false"]);
1816}
1817
1818#[test]
1819fn literal_bool_true_expr() {
1820 check_expr("", "true", &expect!["true"]);
1821}
1822
1823#[test]
1824fn literal_double_expr() {
1825 check_expr("", "4.2", &expect!["4.2"]);
1826}
1827
1828#[test]
1829fn literal_double_trailing_dot_expr() {
1830 check_expr("", "4.", &expect!["4.0"]);
1831}
1832
1833#[test]
1834fn literal_int_expr() {
1835 check_expr("", "42", &expect!["42"]);
1836}
1837
1838#[test]
1839fn literal_int_too_big_expr() {
1840 check_expr(
1841 "",
1842 "9_223_372_036_854_775_808",
1843 &expect!["-9223372036854775808"],
1844 );
1845}
1846
1847#[test]
1848fn literal_pauli_i_expr() {
1849 check_expr("", "PauliI", &expect!["PauliI"]);
1850}
1851
1852#[test]
1853fn literal_pauli_x_expr() {
1854 check_expr("", "PauliX", &expect!["PauliX"]);
1855}
1856
1857#[test]
1858fn literal_pauli_y_expr() {
1859 check_expr("", "PauliY", &expect!["PauliY"]);
1860}
1861
1862#[test]
1863fn literal_pauli_z_expr() {
1864 check_expr("", "PauliZ", &expect!["PauliZ"]);
1865}
1866
1867#[test]
1868fn literal_result_one_expr() {
1869 check_expr("", "One", &expect!["One"]);
1870}
1871
1872#[test]
1873fn literal_result_zero_expr() {
1874 check_expr("", "Zero", &expect!["Zero"]);
1875}
1876
1877#[test]
1878fn literal_string_expr() {
1879 check_expr("", r#""foo""#, &expect!["foo"]);
1880}
1881
1882#[test]
1883fn literal_tuple_expr() {
1884 check_expr("", "(1, 2, 3)", &expect!["(1, 2, 3)"]);
1885}
1886
1887#[test]
1888fn literal_tuple_singleton_expr() {
1889 check_expr("", "(1,)", &expect!["(1,)"]);
1890}
1891
1892#[test]
1893fn literal_tuple_mixed_expr() {
1894 check_expr(
1895 "",
1896 "(1, One, 1.0, [1, 2, 3])",
1897 &expect!["(1, One, 1.0, [1, 2, 3])"],
1898 );
1899}
1900
1901#[test]
1902fn paren_expr() {
1903 check_expr("", "(42)", &expect!["42"]);
1904}
1905
1906#[test]
1907fn range_all_expr() {
1908 check_expr("", "...", &expect!["..."]);
1909}
1910
1911#[test]
1912fn range_end_expr() {
1913 check_expr("", "...3", &expect!["...3"]);
1914}
1915
1916#[test]
1917fn range_step_end_expr() {
1918 check_expr("", "...2..3", &expect!["...2..3"]);
1919}
1920
1921#[test]
1922fn range_start_expr() {
1923 check_expr("", "1...", &expect!["1..."]);
1924}
1925
1926#[test]
1927fn range_start_end_expr() {
1928 check_expr("", "1..3", &expect!["1..3"]);
1929}
1930
1931#[test]
1932fn range_start_step_expr() {
1933 check_expr("", "1..2...", &expect!["1..2..."]);
1934}
1935
1936#[test]
1937fn range_start_step_end_expr() {
1938 check_expr("", "1..2..3", &expect!["1..2..3"]);
1939}
1940
1941#[test]
1942fn repeat_until_expr() {
1943 check_expr(
1944 "",
1945 indoc! {"{
1946 mutable x = 0;
1947 repeat {
1948 set x = x + 1;
1949 }
1950 until x >= 3;
1951 x
1952 }"},
1953 &expect!["3"],
1954 );
1955}
1956
1957#[test]
1958fn repeat_until_fixup_expr() {
1959 check_expr(
1960 "",
1961 indoc! {"{
1962 mutable x = 0;
1963 repeat {}
1964 until x >= 3
1965 fixup {
1966 set x = x + 1;
1967 }
1968 x
1969 }"},
1970 &expect!["3"],
1971 );
1972}
1973
1974#[test]
1975fn return_expr() {
1976 check_expr("", "return 4", &expect!["4"]);
1977}
1978
1979#[test]
1980fn return_shortcut_expr() {
1981 check_expr(
1982 "",
1983 r#"{return 4; fail "Shouldn't get here...";}"#,
1984 &expect!["4"],
1985 );
1986}
1987
1988#[test]
1989fn tuple_expr() {
1990 check_expr("", "(1, 2, 3)", &expect!["(1, 2, 3)"]);
1991}
1992
1993#[test]
1994fn unop_bitwise_not_big_int_expr() {
1995 check_expr(
1996 "",
1997 "~~~(9_223_372_036_854_775_808L)",
1998 &expect!["-9223372036854775809"],
1999 );
2000}
2001
2002#[test]
2003fn while_expr() {
2004 check_expr(
2005 "",
2006 indoc! {"{
2007 mutable x = 0;
2008 while x < 10 {
2009 set x = x + 1;
2010 }
2011 x
2012 }"},
2013 &expect!["10"],
2014 );
2015}
2016
2017#[test]
2018fn while_false_shortcut_expr() {
2019 check_expr(
2020 "",
2021 r#"while false { fail "Shouldn't fail" }"#,
2022 &expect!["()"],
2023 );
2024}
2025
2026#[test]
2027fn cond_expr() {
2028 check_expr("", "true ? 1 | 0", &expect!["1"]);
2029}
2030
2031#[test]
2032fn cond_false_expr() {
2033 check_expr("", "false ? 1 | 0", &expect!["0"]);
2034}
2035
2036#[test]
2037fn cond_shortcircuit_expr() {
2038 check_expr("", r#"true ? 1 | fail "Shouldn't fail""#, &expect!["1"]);
2039}
2040
2041#[test]
2042fn cond_false_shortcircuit_expr() {
2043 check_expr("", r#"false ? fail "Shouldn't fail" | 0"#, &expect!["0"]);
2044}
2045
2046#[test]
2047fn update_expr() {
2048 check_expr("", "[1, 2, 3] w/ 2 <- 4", &expect!["[1, 2, 4]"]);
2049}
2050
2051#[test]
2052fn update_invalid_index_range_expr() {
2053 check_expr(
2054 "",
2055 "[1, 2, 3] w/ 7 <- 4",
2056 &expect![[r#"
2057 (
2058 IndexOutOfRange(
2059 7,
2060 PackageSpan {
2061 package: PackageId(
2062 2,
2063 ),
2064 span: Span {
2065 lo: 13,
2066 hi: 14,
2067 },
2068 },
2069 ),
2070 [],
2071 )
2072 "#]],
2073 );
2074}
2075
2076#[test]
2077fn update_invalid_index_negative_expr() {
2078 check_expr(
2079 "",
2080 "[1, 2, 3] w/ -1 <- 4",
2081 &expect![[r#"
2082 (
2083 InvalidNegativeInt(
2084 -1,
2085 PackageSpan {
2086 package: PackageId(
2087 2,
2088 ),
2089 span: Span {
2090 lo: 13,
2091 hi: 15,
2092 },
2093 },
2094 ),
2095 [],
2096 )
2097 "#]],
2098 );
2099}
2100
2101#[test]
2102fn update_array_index_var() {
2103 check_expr(
2104 "",
2105 indoc! {"{
2106 let xs = [2];
2107 let i = 0;
2108 xs w/ i <- 3
2109 }"},
2110 &expect!["[3]"],
2111 );
2112}
2113
2114#[test]
2115fn update_array_index_expr() {
2116 check_expr(
2117 "",
2118 indoc! {"{
2119 let xs = [1, 2];
2120 let i = 0;
2121 xs w/ i + 1 <- 3
2122 }"},
2123 &expect!["[1, 3]"],
2124 );
2125}
2126
2127#[test]
2128fn struct_cons() {
2129 check_expr(
2130 indoc! {"
2131 namespace A {
2132 struct Pair { First : Int, Second : Int }
2133 }
2134 "},
2135 indoc! {"{
2136 open A;
2137 new Pair { First = 1, Second = 2}
2138 }"},
2139 &expect!["(1, 2)"],
2140 );
2141}
2142
2143#[test]
2144fn struct_copy_cons() {
2145 check_expr(
2146 indoc! {"
2147 namespace A {
2148 struct Pair { First : Int, Second : Int }
2149 }
2150 "},
2151 indoc! {"{
2152 open A;
2153 let p = new Pair { First = 1, Second = 2};
2154 new Pair { ...p, First = 3 }
2155 }"},
2156 &expect!["(3, 2)"],
2157 );
2158}
2159
2160#[test]
2161fn update_udt_known_field_name() {
2162 check_expr(
2163 indoc! {"
2164 namespace A {
2165 newtype Pair = (First : Int, Second : Int);
2166 }
2167 "},
2168 indoc! {"{
2169 open A;
2170 let p = Pair(1, 2);
2171 p w/ First <- 3
2172 }"},
2173 &expect!["(3, 2)"],
2174 );
2175}
2176
2177#[test]
2178fn update_udt_nested_field() {
2179 check_expr(
2180 indoc! {"
2181 namespace A {
2182 newtype Triple = (First : Int, (Second : Int, Third : Int));
2183 }
2184 "},
2185 indoc! {"{
2186 open A;
2187 let p = Triple(1, (2, 3));
2188 p w/ Third <- 4
2189 }"},
2190 &expect!["(1, (2, 4))"],
2191 );
2192}
2193
2194#[test]
2195fn update_range_start() {
2196 check_expr("", "1..2..3 w/ Start <- 10", &expect!["10..2..3"]);
2197}
2198
2199#[test]
2200fn update_range_from_start() {
2201 check_expr("", "1..2... w/ Start <- 10", &expect!["10..2..."]);
2202}
2203
2204#[test]
2205fn update_range_step() {
2206 check_expr("", "1..2..3 w/ Step <- 10", &expect!["1..10..3"]);
2207}
2208
2209#[test]
2210fn update_range_from_step() {
2211 check_expr("", "1..2... w/ Step <- 10", &expect!["1..10..."]);
2212}
2213
2214#[test]
2215fn update_range_to_step() {
2216 check_expr("", "...2..3 w/ Step <- 10", &expect!["...10..3"]);
2217}
2218
2219#[test]
2220fn update_range_full_step() {
2221 check_expr("", "...2... w/ Step <- 10", &expect!["...10..."]);
2222}
2223
2224#[test]
2225fn update_range_end() {
2226 check_expr("", "1..2..3 w/ End <- 10", &expect!["1..2..10"]);
2227}
2228
2229#[test]
2230fn update_range_to_end() {
2231 check_expr("", "...2..3 w/ End <- 10", &expect!["...2..10"]);
2232}
2233
2234#[test]
2235fn update_array_with_range() {
2236 check_expr("", "[0, 1, 2] w/ 1..2 <- [10, 11]", &expect!["[0, 10, 11]"]);
2237}
2238
2239#[test]
2240fn update_array_with_range_start() {
2241 check_expr(
2242 "",
2243 "[0, 1, 2, 3] w/ 1... <- [10, 11]",
2244 &expect!["[0, 10, 11, 3]"],
2245 );
2246}
2247
2248#[test]
2249fn update_array_with_range_step() {
2250 check_expr(
2251 "",
2252 "[0, 1, 2, 3] w/ ...2... <- [10, 11]",
2253 &expect!["[10, 1, 11, 3]"],
2254 );
2255}
2256
2257#[test]
2258fn update_array_with_range_end() {
2259 check_expr(
2260 "",
2261 "[0, 1, 2, 3] w/ ...2 <- [10, 11, 12, 13]",
2262 &expect!["[10, 11, 12, 3]"],
2263 );
2264}
2265
2266#[test]
2267fn update_array_with_range_fully_open() {
2268 check_expr(
2269 "",
2270 "[0, 1, 2, 3] w/ ... <- [10, 11, 12, 13]",
2271 &expect!["[10, 11, 12, 13]"],
2272 );
2273}
2274
2275#[test]
2276fn update_array_with_range_reverse() {
2277 check_expr(
2278 "",
2279 "[0, 1, 2, 3] w/ 2..-1..0 <- [10, 11]",
2280 &expect!["[0, 11, 10, 3]"],
2281 );
2282}
2283
2284#[test]
2285fn update_array_with_range_out_of_range_err() {
2286 check_expr(
2287 "",
2288 "[0, 1, 2, 3] w/ 1..5 <- [10, 11, 12, 13]",
2289 &expect![[r#"
2290 (
2291 IndexOutOfRange(
2292 4,
2293 PackageSpan {
2294 package: PackageId(
2295 2,
2296 ),
2297 span: Span {
2298 lo: 16,
2299 hi: 20,
2300 },
2301 },
2302 ),
2303 [],
2304 )
2305 "#]],
2306 );
2307}
2308
2309#[test]
2310fn update_array_with_range_negative_index_err() {
2311 check_expr(
2312 "",
2313 "[0, 1, 2, 3] w/ -1..0 <- [10, 11, 12, 13]",
2314 &expect![[r#"
2315 (
2316 InvalidIndex(
2317 -1,
2318 PackageSpan {
2319 package: PackageId(
2320 2,
2321 ),
2322 span: Span {
2323 lo: 16,
2324 hi: 21,
2325 },
2326 },
2327 ),
2328 [],
2329 )
2330 "#]],
2331 );
2332}
2333
2334#[test]
2335fn update_array_with_range_zero_step_err() {
2336 check_expr(
2337 "",
2338 "[0, 1, 2, 3] w/ ...0... <- [10, 11, 12, 13]",
2339 &expect![[r#"
2340 (
2341 RangeStepZero(
2342 PackageSpan {
2343 package: PackageId(
2344 2,
2345 ),
2346 span: Span {
2347 lo: 16,
2348 hi: 23,
2349 },
2350 },
2351 ),
2352 [],
2353 )
2354 "#]],
2355 );
2356}
2357
2358#[test]
2359fn update_array_with_range_bigger_than_update() {
2360 check_expr(
2361 "",
2362 "[0, 1, 2, 3] w/ 1..3 <- [10]",
2363 &expect!["[0, 10, 2, 3]"],
2364 );
2365}
2366
2367#[test]
2368fn update_array_with_range_smaller_than_update() {
2369 check_expr(
2370 "",
2371 "[0, 1, 2, 3] w/ 1..3 <- [10, 11, 12, 13]",
2372 &expect!["[0, 10, 11, 12]"],
2373 );
2374}
2375
2376#[test]
2377fn update_array_with_range_open_ended_bigger_than_update() {
2378 check_expr(
2379 "",
2380 "[0, 1, 2, 3] w/ 1... <- [10]",
2381 &expect!["[0, 10, 2, 3]"],
2382 );
2383}
2384
2385#[test]
2386fn update_array_with_range_open_ended_smaller_than_update() {
2387 check_expr(
2388 "",
2389 "[0, 1, 2, 3] w/ 1... <- [10, 11, 12, 13]",
2390 &expect!["[0, 10, 11, 12]"],
2391 );
2392}
2393
2394#[test]
2395fn update_array_with_range_empty_update() {
2396 check_expr("", "[0, 1, 2, 3] w/ 1..3 <- []", &expect!["[0, 1, 2, 3]"]);
2397}
2398
2399#[test]
2400fn assignupdate_expr() {
2401 check_expr(
2402 "",
2403 indoc! {"{
2404 mutable x = [1, 2, 3];
2405 set x w/= 2 <- 4;
2406 x
2407 }"},
2408 &expect!["[1, 2, 4]"],
2409 );
2410}
2411
2412#[test]
2413fn assignupdate_on_copy_should_work() {
2414 check_expr(
2415 "",
2416 indoc! {"{
2417 let x = [1, 2, 3];
2418 mutable y = x;
2419 set y w/= 2 <- 4;
2420 (x, y)
2421 }"},
2422 &expect!["([1, 2, 3], [1, 2, 4])"],
2423 );
2424}
2425
2426#[test]
2427fn assignupdate_out_of_range_err() {
2428 check_expr(
2429 "",
2430 indoc! {"{
2431 mutable x = [1, 2, 3];
2432 set x w/= 4 <- 4;
2433 x
2434 }"},
2435 &expect![[r#"
2436 (
2437 IndexOutOfRange(
2438 4,
2439 PackageSpan {
2440 package: PackageId(
2441 2,
2442 ),
2443 span: Span {
2444 lo: 43,
2445 hi: 44,
2446 },
2447 },
2448 ),
2449 [],
2450 )
2451 "#]],
2452 );
2453}
2454
2455#[test]
2456fn assignupdate_expr_negative_index_err() {
2457 check_expr(
2458 "",
2459 indoc! {"{
2460 mutable x = [1, 2, 3];
2461 set x w/= -1 <- 4;
2462 x
2463 }"},
2464 &expect![[r#"
2465 (
2466 InvalidNegativeInt(
2467 -1,
2468 PackageSpan {
2469 package: PackageId(
2470 2,
2471 ),
2472 span: Span {
2473 lo: 43,
2474 hi: 45,
2475 },
2476 },
2477 ),
2478 [],
2479 )
2480 "#]],
2481 );
2482}
2483
2484#[test]
2485fn assignupdate_expr_using_field_name() {
2486 check_expr(
2487 indoc! {"
2488 namespace A {
2489 newtype Pair = (First : Int, Second : Int);
2490 }
2491 "},
2492 indoc! {"{
2493 open A;
2494 mutable p = Pair(1, 2);
2495 set p w/= First <- 3;
2496 p
2497 }"},
2498 &expect!["(3, 2)"],
2499 );
2500}
2501
2502#[test]
2503fn assignupdate_expr_using_range() {
2504 check_expr(
2505 "",
2506 indoc! {"{
2507 mutable x = [1, 2, 3];
2508 set x w/= 1..2 <- [10, 11];
2509 x
2510 }"},
2511 &expect!["[1, 10, 11]"],
2512 );
2513}
2514
2515#[test]
2516fn assignupdate_expr_using_range_start() {
2517 check_expr(
2518 "",
2519 indoc! {"{
2520 mutable x = [1, 2, 3, 4];
2521 set x w/= 1... <- [10, 11];
2522 x
2523 }"},
2524 &expect!["[1, 10, 11, 4]"],
2525 );
2526}
2527
2528#[test]
2529fn assignupdate_expr_using_range_step() {
2530 check_expr(
2531 "",
2532 indoc! {"{
2533 mutable x = [1, 2, 3, 4];
2534 set x w/= ...2... <- [10, 11];
2535 x
2536 }"},
2537 &expect!["[10, 2, 11, 4]"],
2538 );
2539}
2540
2541#[test]
2542fn assignupdate_expr_using_range_end() {
2543 check_expr(
2544 "",
2545 indoc! {"{
2546 mutable x = [1, 2, 3, 4];
2547 set x w/= ...2 <- [10, 11, 12, 13];
2548 x
2549 }"},
2550 &expect!["[10, 11, 12, 4]"],
2551 );
2552}
2553
2554#[test]
2555fn assignupdate_expr_using_range_fully_open() {
2556 check_expr(
2557 "",
2558 indoc! {"{
2559 mutable x = [1, 2, 3, 4];
2560 set x w/= ... <- [10, 11, 12, 13];
2561 x
2562 }"},
2563 &expect!["[10, 11, 12, 13]"],
2564 );
2565}
2566
2567#[test]
2568fn assignupdate_expr_using_range_reverse() {
2569 check_expr(
2570 "",
2571 indoc! {"{
2572 mutable x = [1, 2, 3, 4];
2573 set x w/= 2..-1..0 <- [10, 11];
2574 x
2575 }"},
2576 &expect!["[1, 11, 10, 4]"],
2577 );
2578}
2579
2580#[test]
2581fn assignupdate_expr_using_range_bigger_than_update() {
2582 check_expr(
2583 "",
2584 indoc! {"{
2585 mutable x = [1, 2, 3, 4];
2586 set x w/= 1..3 <- [10];
2587 x
2588 }"},
2589 &expect!["[1, 10, 3, 4]"],
2590 );
2591}
2592
2593#[test]
2594fn assignupdate_expr_using_range_smaller_than_update() {
2595 check_expr(
2596 "",
2597 indoc! {"{
2598 mutable x = [1, 2, 3, 4];
2599 set x w/= 1..3 <- [10, 11, 12, 13];
2600 x
2601 }"},
2602 &expect!["[1, 10, 11, 12]"],
2603 );
2604}
2605
2606#[test]
2607fn assignupdate_expr_using_range_open_ended_bigger_than_update() {
2608 check_expr(
2609 "",
2610 indoc! {"{
2611 mutable x = [1, 2, 3, 4];
2612 set x w/= 1... <- [10, 11];
2613 x
2614 }"},
2615 &expect!["[1, 10, 11, 4]"],
2616 );
2617}
2618
2619#[test]
2620fn assignupdate_expr_using_range_open_ended_smaller_than_update() {
2621 check_expr(
2622 "",
2623 indoc! {"{
2624 mutable x = [1, 2, 3, 4];
2625 set x w/= 1... <- [10, 11, 12, 13];
2626 x
2627 }"},
2628 &expect!["[1, 10, 11, 12]"],
2629 );
2630}
2631
2632#[test]
2633fn assignupdate_expr_using_range_empty_update() {
2634 check_expr(
2635 "",
2636 indoc! {"{
2637 mutable x = [1, 2, 3, 4];
2638 set x w/= 1..3 <- [];
2639 x
2640 }"},
2641 &expect!["[1, 2, 3, 4]"],
2642 );
2643}
2644
2645#[test]
2646fn assignupdate_expr_using_range_out_of_range_err() {
2647 check_expr(
2648 "",
2649 indoc! {"{
2650 mutable x = [1, 2, 3, 4];
2651 set x w/= 1..5 <- [10, 11, 12, 13];
2652 x
2653 }"},
2654 &expect![[r#"
2655 (
2656 IndexOutOfRange(
2657 4,
2658 PackageSpan {
2659 package: PackageId(
2660 2,
2661 ),
2662 span: Span {
2663 lo: 46,
2664 hi: 50,
2665 },
2666 },
2667 ),
2668 [],
2669 )
2670 "#]],
2671 );
2672}
2673
2674#[test]
2675fn assignupdate_expr_using_range_negative_index_err() {
2676 check_expr(
2677 "",
2678 indoc! {"{
2679 mutable x = [1, 2, 3, 4];
2680 set x w/= -1..0 <- [10, 11, 12, 13];
2681 x
2682 }"},
2683 &expect![[r#"
2684 (
2685 InvalidNegativeInt(
2686 -1,
2687 PackageSpan {
2688 package: PackageId(
2689 2,
2690 ),
2691 span: Span {
2692 lo: 46,
2693 hi: 51,
2694 },
2695 },
2696 ),
2697 [],
2698 )
2699 "#]],
2700 );
2701}
2702
2703#[test]
2704fn unop_bitwise_not_int_expr() {
2705 check_expr("", "~~~(13)", &expect!["-14"]);
2706}
2707
2708#[test]
2709fn unop_negate_big_int_expr() {
2710 check_expr(
2711 "",
2712 "-(9_223_372_036_854_775_808L)",
2713 &expect!["-9223372036854775808"],
2714 );
2715}
2716
2717#[test]
2718fn unop_negate_double_expr() {
2719 check_expr("", "-(3.4)", &expect!["-3.4"]);
2720}
2721
2722#[test]
2723fn unop_negate_int_expr() {
2724 check_expr("", "-(13)", &expect!["-13"]);
2725}
2726
2727#[test]
2728fn unop_negate_int_overflow_expr() {
2729 check_expr(
2730 "",
2731 "-(9_223_372_036_854_775_808)",
2732 &expect!["-9223372036854775808"],
2733 );
2734}
2735
2736#[test]
2737fn unop_negate_negative_int_expr() {
2738 check_expr("", "-(-(13))", &expect!["13"]);
2739}
2740
2741#[test]
2742fn unop_not_bool_expr() {
2743 check_expr("", "not false", &expect!["true"]);
2744}
2745
2746#[test]
2747fn unop_positive_big_int_expr() {
2748 check_expr(
2749 "",
2750 "+(9_223_372_036_854_775_808L)",
2751 &expect!["9223372036854775808"],
2752 );
2753}
2754
2755#[test]
2756fn unop_positive_double_expr() {
2757 check_expr("", "+(3.4)", &expect!["3.4"]);
2758}
2759
2760#[test]
2761fn unop_positive_int_expr() {
2762 check_expr("", "+(13)", &expect!["13"]);
2763}
2764
2765#[test]
2766fn unop_adjoint_functor_expr() {
2767 check_expr(
2768 indoc! {"
2769 namespace Test {
2770 operation Foo() : Unit is Adj + Ctl {
2771 body ... {}
2772 }
2773 }
2774 "},
2775 "Adjoint Test.Foo",
2776 &expect!["Adjoint <item 1 in package 2>"],
2777 );
2778}
2779
2780#[test]
2781fn unop_controlled_functor_expr() {
2782 check_expr(
2783 indoc! {"
2784 namespace Test {
2785 operation Foo() : Unit is Adj + Ctl {
2786 body ... {}
2787 }
2788 }
2789 "},
2790 "Controlled Test.Foo",
2791 &expect!["Controlled <item 1 in package 2>"],
2792 );
2793}
2794
2795#[test]
2796fn unop_adjoint_adjoint_functor_expr() {
2797 check_expr(
2798 indoc! {"
2799 namespace Test {
2800 operation Foo() : Unit is Adj + Ctl {
2801 body ... {}
2802 }
2803 }
2804 "},
2805 "Adjoint (Adjoint Test.Foo)",
2806 &expect!["<item 1 in package 2>"],
2807 );
2808}
2809
2810#[test]
2811fn unop_controlled_adjoint_functor_expr() {
2812 check_expr(
2813 indoc! {"
2814 namespace Test {
2815 operation Foo() : Unit is Adj + Ctl {
2816 body ... {}
2817 }
2818 }
2819 "},
2820 "Controlled Adjoint Test.Foo",
2821 &expect!["Controlled Adjoint <item 1 in package 2>"],
2822 );
2823}
2824
2825#[test]
2826fn unop_adjoint_controlled_functor_expr() {
2827 check_expr(
2828 indoc! {"
2829 namespace Test {
2830 operation Foo() : Unit is Adj + Ctl {
2831 body ... {}
2832 }
2833 }
2834 "},
2835 "Adjoint Controlled Test.Foo",
2836 &expect!["Controlled Adjoint <item 1 in package 2>"],
2837 );
2838}
2839
2840#[test]
2841fn unop_controlled_controlled_functor_expr() {
2842 check_expr(
2843 indoc! {"
2844 namespace Test {
2845 operation Foo() : Unit is Adj + Ctl {
2846 body ... {}
2847 }
2848 }
2849 "},
2850 "Controlled (Controlled Test.Foo)",
2851 &expect!["Controlled Controlled <item 1 in package 2>"],
2852 );
2853}
2854
2855#[test]
2856fn if_true_expr() {
2857 check_expr(
2858 "",
2859 r#"if true {return "Got Here!";}"#,
2860 &expect!["Got Here!"],
2861 );
2862}
2863
2864#[test]
2865fn if_false_expr() {
2866 check_expr(
2867 "",
2868 r#"if false {return "Shouldn't get here...";}"#,
2869 &expect!["()"],
2870 );
2871}
2872
2873#[test]
2874fn if_else_true_expr() {
2875 check_expr(
2876 "",
2877 r#"if true {return "Got Here!";} else {return "Shouldn't get here..."}"#,
2878 &expect!["Got Here!"],
2879 );
2880}
2881
2882#[test]
2883fn if_else_false_expr() {
2884 check_expr(
2885 "",
2886 r#"if false {return "Shouldn't get here...";} else {return "Got Here!"}"#,
2887 &expect!["Got Here!"],
2888 );
2889}
2890
2891#[test]
2892fn if_elif_true_true_expr() {
2893 check_expr(
2894 "",
2895 r#"if true {return "Got Here!";} elif true {return"Shouldn't get here..."}"#,
2896 &expect!["Got Here!"],
2897 );
2898}
2899
2900#[test]
2901fn if_elif_false_true_expr() {
2902 check_expr(
2903 "",
2904 r#"if false {return "Shouldn't get here...";} elif true {return "Got Here!"}"#,
2905 &expect!["Got Here!"],
2906 );
2907}
2908
2909#[test]
2910fn if_elif_false_false_expr() {
2911 check_expr(
2912 "",
2913 r#"if false {return "Shouldn't get here...";} elif false {return "Shouldn't get here..."}"#,
2914 &expect!["()"],
2915 );
2916}
2917
2918#[test]
2919fn if_elif_else_true_true_expr() {
2920 check_expr(
2921 "",
2922 r#"if true {return "Got Here!";} elif true {return "Shouldn't get here..."} else {return "Shouldn't get here..."}"#,
2923 &expect!["Got Here!"],
2924 );
2925}
2926
2927#[test]
2928fn if_elif_else_false_true_expr() {
2929 check_expr(
2930 "",
2931 r#"if false {return "Shouldn't get here...";} elif true {return "Got Here!"} else {return "Shouldn't get here..."}"#,
2932 &expect!["Got Here!"],
2933 );
2934}
2935
2936#[test]
2937fn if_elif_else_false_false_expr() {
2938 check_expr(
2939 "",
2940 r#"if false {return "Shouldn't get here...";} elif false {return "Shouldn't get here..."} else {return "Got Here!"}"#,
2941 &expect!["Got Here!"],
2942 );
2943}
2944
2945#[test]
2946fn call_expr() {
2947 check_expr(
2948 indoc! {"
2949 namespace Test {
2950 function Answer() : Int {
2951 42
2952 }
2953 }
2954 "},
2955 "Test.Answer()",
2956 &expect!["42"],
2957 );
2958}
2959
2960#[test]
2961fn call_return_expr() {
2962 check_expr(
2963 indoc! {"
2964 namespace Test {
2965 function Answer() : Int {
2966 return 42;
2967 }
2968 }
2969 "},
2970 "Test.Answer()",
2971 &expect!["42"],
2972 );
2973}
2974
2975#[test]
2976fn call_args_expr() {
2977 check_expr(
2978 indoc! {"
2979 namespace Test {
2980 function Echo(val : Int) : Int {
2981 return val;
2982 }
2983 }
2984 "},
2985 "Test.Echo(42)",
2986 &expect!["42"],
2987 );
2988}
2989
2990#[test]
2991fn call_multiple_args_expr() {
2992 check_expr(
2993 indoc! {"
2994 namespace Test {
2995 function Echo(val1 : Int, val2 : Int) : (Int, Int) {
2996 return (val1, val2);
2997 }
2998 }
2999 "},
3000 "Test.Echo(42, 43)",
3001 &expect!["(42, 43)"],
3002 );
3003}
3004
3005#[test]
3006fn call_tuple_args_expr() {
3007 check_expr(
3008 indoc! {"
3009 namespace Test {
3010 function MakeList(val1 : (Int, Int), val2 : Int) : Int[] {
3011 let (v1, v2) = val1;
3012 return [v1, v2, val2];
3013 }
3014 }
3015 "},
3016 "Test.MakeList((42, 43), 44)",
3017 &expect!["[42, 43, 44]"],
3018 );
3019}
3020
3021#[test]
3022fn call_call_expr() {
3023 check_expr(
3024 indoc! {"
3025 namespace Test {
3026 function TupleToList(tup : (Int, Int)) : Int[] {
3027 let (val, size) = tup;
3028 return MakeList(val, size);
3029 }
3030 function MakeList(val : Int, size : Int) : Int[] {
3031 return [val, size = size];
3032 }
3033 }
3034 "},
3035 "Test.TupleToList((3, 2))",
3036 &expect!["[3, 3]"],
3037 );
3038}
3039
3040#[test]
3041fn call_adjoint_expr() {
3042 check_expr(
3043 indoc! {r#"
3044 namespace Test {
3045 operation Foo() : Unit is Adj + Ctl {
3046 body (...) {
3047 fail "Body Implementation";
3048 }
3049 adjoint (...) {
3050 fail "Adjoint Implementation";
3051 }
3052 controlled (ctls, ...) {
3053 fail "Controlled Implementation";
3054 }
3055 controlled adjoint (ctls, ...) {
3056 fail "Controlled Adjoint Implementation";
3057 }
3058 }
3059 }
3060 "#},
3061 "Adjoint Test.Foo()",
3062 &expect![[r#"
3063 (
3064 UserFail(
3065 "Adjoint Implementation",
3066 PackageSpan {
3067 package: PackageId(
3068 2,
3069 ),
3070 span: Span {
3071 lo: 185,
3072 hi: 214,
3073 },
3074 },
3075 ),
3076 [
3077 Frame {
3078 span: Span {
3079 lo: 185,
3080 hi: 214,
3081 },
3082 id: StoreItemId {
3083 package: PackageId(
3084 2,
3085 ),
3086 item: LocalItemId(
3087 1,
3088 ),
3089 },
3090 caller: PackageId(
3091 2,
3092 ),
3093 functor: FunctorApp {
3094 adjoint: true,
3095 controlled: 0,
3096 },
3097 },
3098 ],
3099 )
3100 "#]],
3101 );
3102}
3103
3104#[test]
3105fn call_adjoint_adjoint_expr() {
3106 check_expr(
3107 indoc! {r#"
3108 namespace Test {
3109 operation Foo() : Unit is Adj + Ctl {
3110 body (...) {
3111 fail "Body Implementation";
3112 }
3113 adjoint (...) {
3114 fail "Adjoint Implementation";
3115 }
3116 controlled (ctls, ...) {
3117 fail "Controlled Implementation";
3118 }
3119 controlled adjoint (ctls, ...) {
3120 fail "Controlled Adjoint Implementation";
3121 }
3122 }
3123 }
3124 "#},
3125 "Adjoint Adjoint Test.Foo()",
3126 &expect![[r#"
3127 (
3128 UserFail(
3129 "Body Implementation",
3130 PackageSpan {
3131 package: PackageId(
3132 2,
3133 ),
3134 span: Span {
3135 lo: 119,
3136 hi: 145,
3137 },
3138 },
3139 ),
3140 [
3141 Frame {
3142 span: Span {
3143 lo: 119,
3144 hi: 145,
3145 },
3146 id: StoreItemId {
3147 package: PackageId(
3148 2,
3149 ),
3150 item: LocalItemId(
3151 1,
3152 ),
3153 },
3154 caller: PackageId(
3155 2,
3156 ),
3157 functor: FunctorApp {
3158 adjoint: false,
3159 controlled: 0,
3160 },
3161 },
3162 ],
3163 )
3164 "#]],
3165 );
3166}
3167
3168#[test]
3169fn call_adjoint_self_expr() {
3170 check_expr(
3171 indoc! {r#"
3172 namespace Test {
3173 operation Foo() : Unit is Adj + Ctl {
3174 body (...) {
3175 fail "Body Implementation";
3176 }
3177 adjoint self;
3178 controlled (ctls, ...) {
3179 fail "Controlled Implementation";
3180 }
3181 }
3182 }
3183 "#},
3184 "Adjoint Test.Foo()",
3185 &expect![[r#"
3186 (
3187 UserFail(
3188 "Body Implementation",
3189 PackageSpan {
3190 package: PackageId(
3191 2,
3192 ),
3193 span: Span {
3194 lo: 111,
3195 hi: 137,
3196 },
3197 },
3198 ),
3199 [
3200 Frame {
3201 span: Span {
3202 lo: 111,
3203 hi: 137,
3204 },
3205 id: StoreItemId {
3206 package: PackageId(
3207 2,
3208 ),
3209 item: LocalItemId(
3210 1,
3211 ),
3212 },
3213 caller: PackageId(
3214 2,
3215 ),
3216 functor: FunctorApp {
3217 adjoint: true,
3218 controlled: 0,
3219 },
3220 },
3221 ],
3222 )
3223 "#]],
3224 );
3225}
3226
3227#[test]
3228fn check_ctls_count_expr() {
3229 check_expr(
3230 indoc! {r#"
3231 namespace Test {
3232 operation Foo() : Unit is Adj + Ctl {
3233 body (...) {}
3234 adjoint self;
3235 controlled (ctls, ...) {
3236 if Length(ctls) != 3 {
3237 fail "Incorrect ctls count!";
3238 }
3239 }
3240 }
3241 }
3242 "#},
3243 indoc! {"
3244 {
3245 use qs = Qubit[3];
3246 Controlled Test.Foo(qs, ());
3247 }
3248 "},
3249 &expect!["()"],
3250 );
3251}
3252
3253#[test]
3254fn check_ctls_count_nested_expr() {
3255 check_expr(
3256 indoc! {r#"
3257 namespace Test {
3258 operation Foo() : Unit is Adj + Ctl {
3259 body (...) {}
3260 adjoint self;
3261 controlled (ctls, ...) {
3262 if Length(ctls) != 3 {
3263 fail "Incorrect ctls count!";
3264 }
3265 }
3266 }
3267 }
3268 "#},
3269 indoc! {"
3270 {
3271 use qs1 = Qubit[1];
3272 use qs2 = Qubit[2];
3273 Controlled Controlled Test.Foo(qs2, (qs1, ()));
3274 }
3275 "},
3276 &expect!["()"],
3277 );
3278}
3279
3280#[test]
3281fn check_generated_ctl_expr() {
3282 check_expr(
3283 indoc! {r#"
3284 namespace Test {
3285 operation A() : Unit is Ctl {
3286 body ... {}
3287 controlled (ctls, ...) {
3288 if Length(ctls) != 3 {
3289 fail "Incorrect ctls count!";
3290 }
3291 }
3292 }
3293 operation B() : Unit is Ctl {
3294 A();
3295 }
3296 }
3297 "#},
3298 "{use qs = Qubit[3]; Controlled Test.B(qs, ())}",
3299 &expect!["()"],
3300 );
3301}
3302
3303#[test]
3304fn check_generated_ctladj_distrib_expr() {
3305 check_expr(
3306 indoc! {r#"
3307 namespace Test {
3308 operation A() : Unit is Ctl + Adj {
3309 body ... { fail "Shouldn't get here"; }
3310 adjoint self;
3311 controlled (ctls, ...) {
3312 if Length(ctls) != 3 {
3313 fail "Incorrect ctls count!";
3314 }
3315 }
3316 controlled adjoint (ctls, ...) {
3317 if Length(ctls) != 2 {
3318 fail "Incorrect ctls count!";
3319 }
3320 }
3321 }
3322 operation B() : Unit is Ctl + Adj {
3323 body ... { A(); }
3324 adjoint ... { Adjoint A(); }
3325 }
3326 }
3327 "#},
3328 "{use qs = Qubit[2]; Controlled Adjoint Test.B(qs, ())}",
3329 &expect!["()"],
3330 );
3331}
3332
3333#[test]
3334fn global_callable_as_arg() {
3335 check_expr(
3336 indoc! {"
3337 namespace Test {
3338 function PlusOne(x : Int) : Int {
3339 x + 1
3340 }
3341 function ApplyToIntArray(f : (Int -> Int)) : Int[] {
3342 mutable arr = [1, size = 3];
3343 for i in 0..2 {
3344 set arr w/= i <- f(arr[i]);
3345 }
3346 arr
3347 }
3348 }
3349 "},
3350 "Test.ApplyToIntArray(Test.PlusOne)",
3351 &expect!["[2, 2, 2]"],
3352 );
3353}
3354
3355#[test]
3356fn conjugate_output_preserved() {
3357 check_expr("", "{let x = within{}apply{4}; x}", &expect!["4"]);
3358}
3359
3360#[test]
3361fn interpolated_string() {
3362 check_expr("", r#"$"string""#, &expect!["string"]);
3363}
3364
3365#[test]
3366fn interpolated_string_var() {
3367 check_expr(
3368 "",
3369 indoc! {r#"{
3370 let x = 5;
3371 $"{x}"
3372 }"#},
3373 &expect!["5"],
3374 );
3375}
3376
3377#[test]
3378fn interpolated_string_array_index() {
3379 check_expr(
3380 "",
3381 indoc! {r#"{
3382 let xs = [1, 2, 3];
3383 $"{xs[0]}"
3384 }"#},
3385 &expect!["1"],
3386 );
3387}
3388
3389#[test]
3390fn interpolated_string_two_vars() {
3391 check_expr(
3392 "",
3393 indoc! {r#"{
3394 let x = 4;
3395 let y = (true, Zero);
3396 $"{x} {y}"
3397 }"#},
3398 &expect!["4 (true, Zero)"],
3399 );
3400}
3401
3402#[test]
3403fn interpolated_string_nested_normal_string() {
3404 check_expr("", r#"$"{"{}"}""#, &expect!["{}"]);
3405}
3406
3407#[test]
3408fn nested_interpolated_string() {
3409 check_expr(
3410 "",
3411 indoc! {r#"{
3412 let x = 4;
3413 $"{$"{x}"}"
3414 }"#},
3415 &expect!["4"],
3416 );
3417}
3418
3419#[test]
3420fn nested_interpolated_string_with_exprs() {
3421 check_expr(
3422 "",
3423 indoc! {r#"{
3424 let x = "hello!";
3425 let y = 1.5;
3426 $"foo {x + $"bar {y}"} baz"
3427 }"#},
3428 &expect!["foo hello!bar 1.5 baz"],
3429 );
3430}
3431
3432#[test]
3433fn udt_unwrap() {
3434 check_expr(
3435 "",
3436 "{
3437 newtype Foo = (Int, Bool);
3438 let foo = Foo(1, true);
3439 foo!
3440 }",
3441 &expect!["(1, true)"],
3442 );
3443}
3444
3445#[test]
3446fn udt_fields() {
3447 check_expr(
3448 "",
3449 "{
3450 newtype Point = (X : Int, Y : Int);
3451 let p = Point(1, 2);
3452 (p::X, p::Y)
3453 }",
3454 &expect!["(1, 2)"],
3455 );
3456}
3457
3458#[test]
3459fn udt_field_nested() {
3460 check_expr(
3461 "",
3462 "{
3463 newtype Point = (X : Int, (Y : Int, Z : Int));
3464 let p = Point(1, (2, 3));
3465 (p::Y, p::Z)
3466 }",
3467 &expect!["(2, 3)"],
3468 );
3469}
3470
3471#[test]
3472fn lambda_function_empty_closure() {
3473 check_expr("", "{ let f = x -> x + 1; f(1) }", &expect!["2"]);
3474}
3475
3476#[test]
3477fn lambda_function_empty_closure_passed() {
3478 check_expr(
3479 "",
3480 "{ function Foo(f : Int -> Int) : Int { f(2) }; Foo(x -> x + 1) }",
3481 &expect!["3"],
3482 );
3483}
3484
3485#[test]
3486fn lambda_function_closure() {
3487 check_expr(
3488 "",
3489 "{ let x = 5; let f = y -> (x, y); f(2) }",
3490 &expect!["(5, 2)"],
3491 );
3492}
3493
3494#[test]
3495fn lambda_function_closure_passed() {
3496 check_expr(
3497 "",
3498 "{ function Foo(f : Int -> (Int, Int)) : (Int, Int) { f(2) }; let x = 5; Foo(y -> (x, y)) }",
3499 &expect!["(5, 2)"],
3500 );
3501}
3502
3503#[test]
3504fn lambda_function_nested_closure() {
3505 check_expr(
3506 "
3507 namespace A {
3508 function Foo(f : Int -> Int -> (Int, Int, Int, Int)) : (Int, Int, Int, Int) {
3509 f(2)(3)
3510 }
3511
3512 function Bar() : (Int, Int, Int, Int) {
3513 let a = 5;
3514 Foo(b -> {
3515 let c = 1;
3516 d -> (a, b, c, d)
3517 })
3518 }
3519 }
3520 ",
3521 "A.Bar()",
3522 &expect!["(5, 2, 1, 3)"],
3523 );
3524}
3525
3526#[test]
3527fn lambda_operation_empty_closure() {
3528 check_expr(
3529 "
3530 namespace A {
3531 operation Foo(op : Qubit => ()) : Result {
3532 use q = Qubit();
3533 op(q);
3534 MResetZ(q)
3535 }
3536
3537 operation Bar() : Result { Foo(q => X(q)) }
3538 }
3539 ",
3540 "A.Bar()",
3541 &expect!["One"],
3542 );
3543}
3544
3545#[test]
3546fn lambda_operation_closure() {
3547 check_expr(
3548 "
3549 namespace A {
3550 operation Foo(op : () => Result) : Result { op() }
3551 operation Bar() : Result {
3552 use q = Qubit();
3553 X(q);
3554 Foo(() => MResetZ(q))
3555 }
3556 }
3557 ",
3558 "A.Bar()",
3559 &expect!["One"],
3560 );
3561}
3562
3563#[test]
3564fn lambda_operation_controlled() {
3565 check_expr(
3566 "
3567 namespace A {
3568 operation Foo(op : Qubit => Unit is Adj + Ctl, q : Qubit) : Unit is Adj + Ctl { op(q) }
3569 operation Bar() : Result[] {
3570 mutable output = [];
3571 use (ctls, q) = (Qubit[1], Qubit());
3572 let op = q => X(q);
3573 Foo(op, q);
3574 set output += [MResetZ(q)];
3575 Controlled Foo(ctls, (op, q));
3576 set output += [MResetZ(q)];
3577 X(ctls[0]);
3578 Controlled Foo(ctls, (op, q));
3579 set output += [MResetZ(q)];
3580 ResetAll(ctls);
3581 output
3582 }
3583 }
3584 ",
3585 "A.Bar()",
3586 &expect!["[One, Zero, One]"],
3587 );
3588}
3589
3590#[test]
3591fn lambda_operation_controlled_controlled() {
3592 check_expr(
3593 "
3594 namespace A {
3595 operation Foo(op : Qubit => Unit is Adj + Ctl, q : Qubit) : Unit is Adj + Ctl { op(q) }
3596 operation Bar() : Result[] {
3597 mutable output = [];
3598 use (ctls1, ctls2, q) = (Qubit[1], Qubit[1], Qubit());
3599 let op = q => X(q);
3600 Foo(op, q);
3601 set output += [MResetZ(q)];
3602 Controlled Controlled Foo(ctls1, (ctls2, (op, q)));
3603 set output += [MResetZ(q)];
3604 X(ctls1[0]);
3605 X(ctls2[0]);
3606 Controlled Controlled Foo(ctls1, (ctls2, (op, q)));
3607 set output += [MResetZ(q)];
3608 ResetAll(ctls1 + ctls2);
3609 output
3610 }
3611 }
3612 ",
3613 "A.Bar()",
3614 &expect!["[One, Zero, One]"],
3615 );
3616}
3617
3618#[test]
3619fn partial_app_all_holes() {
3620 check_expr(
3621 "",
3622 "{
3623 function F(x : Int, y : Int) : Int { x + y }
3624 let f = F(_, _);
3625 f(1, 2)
3626 }",
3627 &expect!["3"],
3628 );
3629}
3630
3631#[test]
3632fn partial_app_one_fixed_arg() {
3633 check_expr(
3634 "",
3635 "{
3636 function F(x : Int, y : Int) : Int { x + y }
3637 let f = F(_, 2);
3638 f(1)
3639 }",
3640 &expect!["3"],
3641 );
3642}
3643
3644#[test]
3645fn partial_app_nested_tuple() {
3646 check_expr(
3647 "",
3648 "{
3649 function F(a : Int, (b : Int, c : Int, d : Int)) : (Int, Int, Int, Int) { (a, b, c, d) }
3650 let f = F(_, (_, 3, _));
3651 f(1, (2, 4))
3652 }",
3653 &expect!["(1, 2, 3, 4)"],
3654 );
3655}
3656
3657#[test]
3658fn partial_app_arg_with_side_effect() {
3659 check_expr(
3660 "",
3661 "{
3662 operation F(_ : (), x : Int) : Int { x }
3663 use q = Qubit();
3664 let f = F(X(q), _);
3665 let r1 = M(q);
3666 f(1);
3667 let r2 = M(q);
3668 f(2);
3669 let r3 = M(q);
3670 Reset(q);
3671 (r1, r2, r3)
3672 }",
3673 &expect!["(One, One, One)"],
3674 );
3675}
3676
3677#[test]
3678fn partial_app_mutable_arg() {
3679 check_expr(
3680 "",
3681 "{
3682 function F(a : Int, b : Int) : (Int, Int) { (a, b) }
3683 mutable x = 0;
3684 let f = F(x, _);
3685 let r1 = f(1);
3686 set x = 1;
3687 let r2 = f(2);
3688 (r1, r2)
3689 }",
3690 &expect!["((0, 1), (0, 2))"],
3691 );
3692}
3693
3694#[test]
3695fn controlled_operation_with_duplicate_controls_fails() {
3696 check_expr(
3697 "",
3698 "{
3699 use ctl = Qubit();
3700 use q = Qubit();
3701 Controlled I([ctl, ctl], q);
3702 }",
3703 &expect![[r#"
3704 (
3705 QubitUniqueness(
3706 PackageSpan {
3707 package: PackageId(
3708 2,
3709 ),
3710 span: Span {
3711 lo: 86,
3712 hi: 101,
3713 },
3714 },
3715 ),
3716 [
3717 Frame {
3718 span: Span {
3719 lo: 74,
3720 hi: 101,
3721 },
3722 id: StoreItemId {
3723 package: PackageId(
3724 1,
3725 ),
3726 item: LocalItemId(
3727 134,
3728 ),
3729 },
3730 caller: PackageId(
3731 2,
3732 ),
3733 functor: FunctorApp {
3734 adjoint: false,
3735 controlled: 1,
3736 },
3737 },
3738 ],
3739 )
3740 "#]],
3741 );
3742}
3743
3744#[test]
3745fn controlled_operation_with_target_in_controls_fails() {
3746 check_expr(
3747 "",
3748 "{
3749 use ctl = Qubit();
3750 use q = Qubit();
3751 Controlled I([ctl, q], q);
3752 }",
3753 &expect![[r#"
3754 (
3755 QubitUniqueness(
3756 PackageSpan {
3757 package: PackageId(
3758 2,
3759 ),
3760 span: Span {
3761 lo: 86,
3762 hi: 99,
3763 },
3764 },
3765 ),
3766 [
3767 Frame {
3768 span: Span {
3769 lo: 74,
3770 hi: 99,
3771 },
3772 id: StoreItemId {
3773 package: PackageId(
3774 1,
3775 ),
3776 item: LocalItemId(
3777 134,
3778 ),
3779 },
3780 caller: PackageId(
3781 2,
3782 ),
3783 functor: FunctorApp {
3784 adjoint: false,
3785 controlled: 1,
3786 },
3787 },
3788 ],
3789 )
3790 "#]],
3791 );
3792}
3793
3794#[test]
3795fn controlled_operation_with_unique_controls_duplicate_targets_allowed() {
3796 check_expr(
3797 "",
3798 "{
3799 operation DoubleI(q0 : Qubit, q1 : Qubit) : Unit is Ctl {
3800 I(q0);
3801 I(q1);
3802 }
3803 use ctl = Qubit();
3804 use q = Qubit();
3805 Controlled DoubleI([ctl], (q, q));
3806 }",
3807 &expect!["()"],
3808 );
3809}
3810
3811#[test]
3812fn partial_eval_simple_stmt() {
3813 check_partial_eval_stmt(
3814 "",
3815 "{3; {4} 5;}",
3816 &[2_u32.into()],
3817 &expect![[r#"
3818 Package:
3819 Entry Expression: 0
3820 Items:
3821 Item 0 [12-12] (Public):
3822 Namespace (Ident 0 [12-12] "test"): <empty>
3823 Blocks:
3824 Block 0 [0-11] [Type Unit]:
3825 0
3826 1
3827 3
3828 Block 1 [4-7] [Type Int]:
3829 2
3830 Stmts:
3831 Stmt 0 [1-3]: Semi: 1
3832 Stmt 1 [4-7]: Expr: 2
3833 Stmt 2 [5-6]: Expr: 3
3834 Stmt 3 [8-10]: Semi: 4
3835 Exprs:
3836 Expr 0 [0-11] [Type Unit]: Expr Block: 0
3837 Expr 1 [1-2] [Type Int]: Lit: Int(3)
3838 Expr 2 [4-7] [Type Int]: Expr Block: 1
3839 Expr 3 [5-6] [Type Int]: Lit: Int(4)
3840 Expr 4 [8-9] [Type Int]: Lit: Int(5)
3841 Pats:"#]],
3842 &expect!["4"],
3843 );
3844}
3845
3846#[test]
3847fn partial_eval_stmt_with_bound_variable() {
3848 check_partial_eval_stmt(
3849 "",
3850 "{let x = 3; {x} ()}",
3851 &[0_u32.into(), 2_u32.into()],
3852 &expect![[r#"
3853 Package:
3854 Entry Expression: 0
3855 Items:
3856 Item 0 [20-20] (Public):
3857 Namespace (Ident 1 [20-20] "test"): <empty>
3858 Blocks:
3859 Block 0 [0-19] [Type Unit]:
3860 0
3861 1
3862 3
3863 Block 1 [12-15] [Type Int]:
3864 2
3865 Stmts:
3866 Stmt 0 [1-11]: Local (Immutable):
3867 0
3868 1
3869 Stmt 1 [12-15]: Expr: 2
3870 Stmt 2 [13-14]: Expr: 3
3871 Stmt 3 [16-18]: Expr: 4
3872 Exprs:
3873 Expr 0 [0-19] [Type Unit]: Expr Block: 0
3874 Expr 1 [9-10] [Type Int]: Lit: Int(3)
3875 Expr 2 [12-15] [Type Int]: Expr Block: 1
3876 Expr 3 [13-14] [Type Int]: Var: Local 0
3877 Expr 4 [16-18] [Type Unit]: Unit
3878 Pats:
3879 Pat 0 [5-6] [Type Int]: Bind: Ident 0 [5-6] "x""#]],
3880 &expect!["3"],
3881 );
3882}
3883
3884#[test]
3885fn partial_eval_stmt_with_mutable_variable_update() {
3886 check_partial_eval_stmt(
3887 "",
3888 "{mutable x = 0; set x += 1; {x} set x = -1;}",
3889 &[0_u32.into(), 1_u32.into(), 2_u32.into()],
3890 &expect![[r#"
3891 Package:
3892 Entry Expression: 0
3893 Items:
3894 Item 0 [45-45] (Public):
3895 Namespace (Ident 1 [45-45] "test"): <empty>
3896 Blocks:
3897 Block 0 [0-44] [Type Unit]:
3898 0
3899 1
3900 2
3901 4
3902 Block 1 [28-31] [Type Int]:
3903 3
3904 Stmts:
3905 Stmt 0 [1-15]: Local (Mutable):
3906 0
3907 1
3908 Stmt 1 [16-27]: Semi: 2
3909 Stmt 2 [28-31]: Expr: 5
3910 Stmt 3 [29-30]: Expr: 6
3911 Stmt 4 [32-43]: Semi: 7
3912 Exprs:
3913 Expr 0 [0-44] [Type Unit]: Expr Block: 0
3914 Expr 1 [13-14] [Type Int]: Lit: Int(0)
3915 Expr 2 [16-26] [Type Unit]: AssignOp (Add):
3916 3
3917 4
3918 Expr 3 [20-21] [Type Int]: Var: Local 0
3919 Expr 4 [25-26] [Type Int]: Lit: Int(1)
3920 Expr 5 [28-31] [Type Int]: Expr Block: 1
3921 Expr 6 [29-30] [Type Int]: Var: Local 0
3922 Expr 7 [32-42] [Type Unit]: Assign:
3923 8
3924 9
3925 Expr 8 [36-37] [Type Int]: Var: Local 0
3926 Expr 9 [40-42] [Type Int]: UnOp (Neg):
3927 10
3928 Expr 10 [41-42] [Type Int]: Lit: Int(1)
3929 Pats:
3930 Pat 0 [9-10] [Type Int]: Bind: Ident 0 [9-10] "x""#]],
3931 &expect!["1"],
3932 );
3933}
3934
3935#[test]
3936fn partial_eval_stmt_with_mutable_variable_update_out_of_order_works() {
3937 check_partial_eval_stmt(
3938 "",
3939 "{mutable x = 0; set x += 1; {x} set x = -1;}",
3940 &[0_u32.into(), 4_u32.into(), 3_u32.into()],
3941 &expect![[r#"
3942 Package:
3943 Entry Expression: 0
3944 Items:
3945 Item 0 [45-45] (Public):
3946 Namespace (Ident 1 [45-45] "test"): <empty>
3947 Blocks:
3948 Block 0 [0-44] [Type Unit]:
3949 0
3950 1
3951 2
3952 4
3953 Block 1 [28-31] [Type Int]:
3954 3
3955 Stmts:
3956 Stmt 0 [1-15]: Local (Mutable):
3957 0
3958 1
3959 Stmt 1 [16-27]: Semi: 2
3960 Stmt 2 [28-31]: Expr: 5
3961 Stmt 3 [29-30]: Expr: 6
3962 Stmt 4 [32-43]: Semi: 7
3963 Exprs:
3964 Expr 0 [0-44] [Type Unit]: Expr Block: 0
3965 Expr 1 [13-14] [Type Int]: Lit: Int(0)
3966 Expr 2 [16-26] [Type Unit]: AssignOp (Add):
3967 3
3968 4
3969 Expr 3 [20-21] [Type Int]: Var: Local 0
3970 Expr 4 [25-26] [Type Int]: Lit: Int(1)
3971 Expr 5 [28-31] [Type Int]: Expr Block: 1
3972 Expr 6 [29-30] [Type Int]: Var: Local 0
3973 Expr 7 [32-42] [Type Unit]: Assign:
3974 8
3975 9
3976 Expr 8 [36-37] [Type Int]: Var: Local 0
3977 Expr 9 [40-42] [Type Int]: UnOp (Neg):
3978 10
3979 Expr 10 [41-42] [Type Int]: Lit: Int(1)
3980 Pats:
3981 Pat 0 [9-10] [Type Int]: Bind: Ident 0 [9-10] "x""#]],
3982 &expect!["-1"],
3983 );
3984}
3985
3986#[test]
3987fn partial_eval_stmt_with_mutable_variable_update_repeat_stmts_works() {
3988 check_partial_eval_stmt(
3989 "",
3990 "{mutable x = 0; set x += 1; {x} set x = -1;}",
3991 &[0_u32.into(), 1_u32.into(), 1_u32.into(), 3_u32.into()],
3992 &expect![[r#"
3993 Package:
3994 Entry Expression: 0
3995 Items:
3996 Item 0 [45-45] (Public):
3997 Namespace (Ident 1 [45-45] "test"): <empty>
3998 Blocks:
3999 Block 0 [0-44] [Type Unit]:
4000 0
4001 1
4002 2
4003 4
4004 Block 1 [28-31] [Type Int]:
4005 3
4006 Stmts:
4007 Stmt 0 [1-15]: Local (Mutable):
4008 0
4009 1
4010 Stmt 1 [16-27]: Semi: 2
4011 Stmt 2 [28-31]: Expr: 5
4012 Stmt 3 [29-30]: Expr: 6
4013 Stmt 4 [32-43]: Semi: 7
4014 Exprs:
4015 Expr 0 [0-44] [Type Unit]: Expr Block: 0
4016 Expr 1 [13-14] [Type Int]: Lit: Int(0)
4017 Expr 2 [16-26] [Type Unit]: AssignOp (Add):
4018 3
4019 4
4020 Expr 3 [20-21] [Type Int]: Var: Local 0
4021 Expr 4 [25-26] [Type Int]: Lit: Int(1)
4022 Expr 5 [28-31] [Type Int]: Expr Block: 1
4023 Expr 6 [29-30] [Type Int]: Var: Local 0
4024 Expr 7 [32-42] [Type Unit]: Assign:
4025 8
4026 9
4027 Expr 8 [36-37] [Type Int]: Var: Local 0
4028 Expr 9 [40-42] [Type Int]: UnOp (Neg):
4029 10
4030 Expr 10 [41-42] [Type Int]: Lit: Int(1)
4031 Pats:
4032 Pat 0 [9-10] [Type Int]: Bind: Ident 0 [9-10] "x""#]],
4033 &expect!["2"],
4034 );
4035}
4036
4037#[test]
4038fn partial_eval_stmt_with_bool_short_circuit() {
4039 check_partial_eval_stmt(
4040 "",
4041 "{let x = true; { x or false } ();}",
4042 &[0_u32.into(), 2_u32.into()],
4043 &expect![[r#"
4044 Package:
4045 Entry Expression: 0
4046 Items:
4047 Item 0 [35-35] (Public):
4048 Namespace (Ident 1 [35-35] "test"): <empty>
4049 Blocks:
4050 Block 0 [0-34] [Type Unit]:
4051 0
4052 1
4053 3
4054 Block 1 [15-29] [Type Bool]:
4055 2
4056 Stmts:
4057 Stmt 0 [1-14]: Local (Immutable):
4058 0
4059 1
4060 Stmt 1 [15-29]: Expr: 2
4061 Stmt 2 [17-27]: Expr: 3
4062 Stmt 3 [30-33]: Semi: 6
4063 Exprs:
4064 Expr 0 [0-34] [Type Unit]: Expr Block: 0
4065 Expr 1 [9-13] [Type Bool]: Lit: Bool(true)
4066 Expr 2 [15-29] [Type Bool]: Expr Block: 1
4067 Expr 3 [17-27] [Type Bool]: BinOp (OrL):
4068 4
4069 5
4070 Expr 4 [17-18] [Type Bool]: Var: Local 0
4071 Expr 5 [22-27] [Type Bool]: Lit: Bool(false)
4072 Expr 6 [30-32] [Type Unit]: Unit
4073 Pats:
4074 Pat 0 [5-6] [Type Bool]: Bind: Ident 0 [5-6] "x""#]],
4075 &expect!["true"],
4076 );
4077}
4078
4079#[test]
4080fn partial_eval_stmt_with_bool_no_short_circuit() {
4081 check_partial_eval_stmt(
4082 "",
4083 "{let x = false; { x or true } ();}",
4084 &[0_u32.into(), 2_u32.into()],
4085 &expect![[r#"
4086 Package:
4087 Entry Expression: 0
4088 Items:
4089 Item 0 [35-35] (Public):
4090 Namespace (Ident 1 [35-35] "test"): <empty>
4091 Blocks:
4092 Block 0 [0-34] [Type Unit]:
4093 0
4094 1
4095 3
4096 Block 1 [16-29] [Type Bool]:
4097 2
4098 Stmts:
4099 Stmt 0 [1-15]: Local (Immutable):
4100 0
4101 1
4102 Stmt 1 [16-29]: Expr: 2
4103 Stmt 2 [18-27]: Expr: 3
4104 Stmt 3 [30-33]: Semi: 6
4105 Exprs:
4106 Expr 0 [0-34] [Type Unit]: Expr Block: 0
4107 Expr 1 [9-14] [Type Bool]: Lit: Bool(false)
4108 Expr 2 [16-29] [Type Bool]: Expr Block: 1
4109 Expr 3 [18-27] [Type Bool]: BinOp (OrL):
4110 4
4111 5
4112 Expr 4 [18-19] [Type Bool]: Var: Local 0
4113 Expr 5 [23-27] [Type Bool]: Lit: Bool(true)
4114 Expr 6 [30-32] [Type Unit]: Unit
4115 Pats:
4116 Pat 0 [5-6] [Type Bool]: Bind: Ident 0 [5-6] "x""#]],
4117 &expect!["true"],
4118 );
4119}
4120
4121#[test]
4122fn partial_eval_stmt_with_loop() {
4123 check_partial_eval_stmt(
4124 "",
4125 "{mutable x = 0; while x < 3 { set x += 1; } {x} ();}",
4126 &[0_u32.into(), 1_u32.into(), 4_u32.into()],
4127 &expect![[r#"
4128 Package:
4129 Entry Expression: 0
4130 Items:
4131 Item 0 [53-53] (Public):
4132 Namespace (Ident 1 [53-53] "test"): <empty>
4133 Blocks:
4134 Block 0 [0-52] [Type Unit]:
4135 0
4136 1
4137 3
4138 5
4139 Block 1 [28-43] [Type Unit]:
4140 2
4141 Block 2 [44-47] [Type Int]:
4142 4
4143 Stmts:
4144 Stmt 0 [1-15]: Local (Mutable):
4145 0
4146 1
4147 Stmt 1 [16-43]: Expr: 2
4148 Stmt 2 [30-41]: Semi: 6
4149 Stmt 3 [44-47]: Expr: 9
4150 Stmt 4 [45-46]: Expr: 10
4151 Stmt 5 [48-51]: Semi: 11
4152 Exprs:
4153 Expr 0 [0-52] [Type Unit]: Expr Block: 0
4154 Expr 1 [13-14] [Type Int]: Lit: Int(0)
4155 Expr 2 [16-43] [Type Unit]: While:
4156 3
4157 1
4158 Expr 3 [22-27] [Type Bool]: BinOp (Lt):
4159 4
4160 5
4161 Expr 4 [22-23] [Type Int]: Var: Local 0
4162 Expr 5 [26-27] [Type Int]: Lit: Int(3)
4163 Expr 6 [30-40] [Type Unit]: AssignOp (Add):
4164 7
4165 8
4166 Expr 7 [34-35] [Type Int]: Var: Local 0
4167 Expr 8 [39-40] [Type Int]: Lit: Int(1)
4168 Expr 9 [44-47] [Type Int]: Expr Block: 2
4169 Expr 10 [45-46] [Type Int]: Var: Local 0
4170 Expr 11 [48-50] [Type Unit]: Unit
4171 Pats:
4172 Pat 0 [9-10] [Type Int]: Bind: Ident 0 [9-10] "x""#]],
4173 &expect!["3"],
4174 );
4175}
4176
4177#[test]
4178fn partial_eval_stmt_function_calls() {
4179 check_partial_eval_stmt(
4180 indoc! {"
4181 namespace Test {
4182 function Add1(x : Int) : Int { x + 1 }
4183 }
4184 "},
4185 "{let x = Test.Add1(4); {x} Test.Add1(3)}",
4186 &[0_u32.into(), 2_u32.into()],
4187 &expect![[r#"
4188 Package:
4189 Entry Expression: 0
4190 Items:
4191 Item 0 [41-102] (Public):
4192 Namespace (Ident 1 [51-55] "Test"): Item 1
4193 Item 1 [62-100] (Internal):
4194 Parent: 0
4195 Callable 0 [62-100] (function):
4196 name: Ident 0 [71-75] "Add1"
4197 input: 1
4198 output: Int
4199 functors: empty set
4200 implementation: Spec:
4201 SpecImpl:
4202 body: SpecDecl 1 [62-100]: None 2
4203 adj: <none>
4204 ctl: <none>
4205 ctl-adj: <none>
4206 Blocks:
4207 Block 0 [0-40] [Type Int]:
4208 0
4209 1
4210 3
4211 Block 1 [23-26] [Type Int]:
4212 2
4213 Block 2 [91-100] [Type Int]:
4214 4
4215 Stmts:
4216 Stmt 0 [1-22]: Local (Immutable):
4217 0
4218 1
4219 Stmt 1 [23-26]: Expr: 4
4220 Stmt 2 [24-25]: Expr: 5
4221 Stmt 3 [27-39]: Expr: 6
4222 Stmt 4 [93-98]: Expr: 9
4223 Exprs:
4224 Expr 0 [0-40] [Type Int]: Expr Block: 0
4225 Expr 1 [9-21] [Type Int]: Call:
4226 2
4227 3
4228 Expr 2 [9-18] [Type (Int -> Int)]: Var: Item 1
4229 Expr 3 [19-20] [Type Int]: Lit: Int(4)
4230 Expr 4 [23-26] [Type Int]: Expr Block: 1
4231 Expr 5 [24-25] [Type Int]: Var: Local 0
4232 Expr 6 [27-39] [Type Int]: Call:
4233 7
4234 8
4235 Expr 7 [27-36] [Type (Int -> Int)]: Var: Item 1
4236 Expr 8 [37-38] [Type Int]: Lit: Int(3)
4237 Expr 9 [93-98] [Type Int]: BinOp (Add):
4238 10
4239 11
4240 Expr 10 [93-94] [Type Int]: Var: Local 1
4241 Expr 11 [97-98] [Type Int]: Lit: Int(1)
4242 Pats:
4243 Pat 0 [5-6] [Type Int]: Bind: Ident 0 [5-6] "x"
4244 Pat 1 [76-83] [Type Int]: Bind: Ident 1 [76-77] "x""#]],
4245 &expect!["5"],
4246 );
4247}
4248
4249#[test]
4250fn partial_eval_stmt_function_calls_from_library() {
4251 check_partial_eval_stmt(
4252 "",
4253 "{let x = [1, 2, 3]; {Length(x)} 3}",
4254 &[0_u32.into(), 2_u32.into()],
4255 &expect![[r#"
4256 Package:
4257 Entry Expression: 0
4258 Items:
4259 Item 0 [35-35] (Public):
4260 Namespace (Ident 1 [35-35] "test"): <empty>
4261 Blocks:
4262 Block 0 [0-34] [Type Int]:
4263 0
4264 1
4265 3
4266 Block 1 [20-31] [Type Int]:
4267 2
4268 Stmts:
4269 Stmt 0 [1-19]: Local (Immutable):
4270 0
4271 1
4272 Stmt 1 [20-31]: Expr: 5
4273 Stmt 2 [21-30]: Expr: 6
4274 Stmt 3 [32-33]: Expr: 9
4275 Exprs:
4276 Expr 0 [0-34] [Type Int]: Expr Block: 0
4277 Expr 1 [9-18] [Type (Int)[]]: Array:
4278 2
4279 3
4280 4
4281 Expr 2 [10-11] [Type Int]: Lit: Int(1)
4282 Expr 3 [13-14] [Type Int]: Lit: Int(2)
4283 Expr 4 [16-17] [Type Int]: Lit: Int(3)
4284 Expr 5 [20-31] [Type Int]: Expr Block: 1
4285 Expr 6 [21-30] [Type Int]: Call:
4286 7
4287 8
4288 Expr 7 [21-27] [Type ((Int)[] -> Int)]: Var:
4289 res: Item 1 (Package 0)
4290 generics:
4291 Int
4292 Expr 8 [28-29] [Type (Int)[]]: Var: Local 0
4293 Expr 9 [32-33] [Type Int]: Lit: Int(3)
4294 Pats:
4295 Pat 0 [5-6] [Type (Int)[]]: Bind: Ident 0 [5-6] "x""#]],
4296 &expect!["3"],
4297 );
4298}
4299