microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.2.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc_eval/src/tests.rs

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