microsoft/qdk

Public

mirrored from https://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
alex/second-test-harness-take

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc/src/interpret/tests.rs

2106lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4mod given_interpreter {
5 use crate::interpret::{InterpretResult, Interpreter};
6 use expect_test::Expect;
7 use miette::Diagnostic;
8 use qsc_data_structures::{language_features::LanguageFeatures, target::TargetCapabilityFlags};
9 use qsc_eval::{output::CursorReceiver, val::Value};
10 use qsc_frontend::compile::SourceMap;
11 use qsc_passes::PackageType;
12 use std::{fmt::Write, io::Cursor, iter, str::from_utf8};
13
14 fn line(interpreter: &mut Interpreter, line: &str) -> (InterpretResult, String) {
15 let mut cursor = Cursor::new(Vec::<u8>::new());
16 let mut receiver = CursorReceiver::new(&mut cursor);
17 (
18 interpreter.eval_fragments(&mut receiver, line),
19 receiver.dump(),
20 )
21 }
22
23 fn run(interpreter: &mut Interpreter, expr: &str) -> (InterpretResult, String) {
24 let mut cursor = Cursor::new(Vec::<u8>::new());
25 let mut receiver = CursorReceiver::new(&mut cursor);
26 (
27 interpreter.run(&mut receiver, Some(expr), None),
28 receiver.dump(),
29 )
30 }
31
32 fn entry(interpreter: &mut Interpreter) -> (InterpretResult, String) {
33 let mut cursor = Cursor::new(Vec::<u8>::new());
34 let mut receiver = CursorReceiver::new(&mut cursor);
35 (interpreter.eval_entry(&mut receiver), receiver.dump())
36 }
37
38 fn fragment(
39 interpreter: &mut Interpreter,
40 fragments: &str,
41 package: crate::ast::Package,
42 ) -> (InterpretResult, String) {
43 let mut cursor = Cursor::new(Vec::<u8>::new());
44 let mut receiver = CursorReceiver::new(&mut cursor);
45 let result = interpreter.eval_ast_fragments(&mut receiver, fragments, package);
46 (result, receiver.dump())
47 }
48
49 fn invoke(
50 interpreter: &mut Interpreter,
51 callable: &str,
52 args: Value,
53 ) -> (InterpretResult, String) {
54 let mut cursor = Cursor::new(Vec::<u8>::new());
55 let mut receiver = CursorReceiver::new(&mut cursor);
56 let callable = match interpreter.eval_fragments(&mut receiver, callable) {
57 Ok(val) => val,
58 Err(e) => return (Err(e), receiver.dump()),
59 };
60 let result = interpreter.invoke(&mut receiver, callable, args);
61 (result, receiver.dump())
62 }
63
64 mod without_sources {
65 use expect_test::expect;
66 use indoc::indoc;
67
68 use super::*;
69
70 mod without_stdlib {
71 use qsc_frontend::compile::SourceMap;
72 use qsc_passes::PackageType;
73
74 use super::*;
75
76 #[test]
77 fn stdlib_members_should_be_unavailable() {
78 let store = crate::PackageStore::new(crate::compile::core());
79 let mut interpreter = Interpreter::new(
80 SourceMap::default(),
81 PackageType::Lib,
82 TargetCapabilityFlags::all(),
83 LanguageFeatures::default(),
84 store,
85 &[],
86 )
87 .expect("interpreter should be created");
88
89 let (result, output) = line(&mut interpreter, "Message(\"_\")");
90 is_only_error(
91 &result,
92 &output,
93 &expect![[r#"
94 name error: `Message` not found
95 [line_0] [Message]
96 type error: insufficient type information to infer type
97 [line_0] [Message("_")]
98 "#]],
99 );
100 }
101 }
102
103 #[test]
104 fn stdlib_members_should_be_available() {
105 let mut interpreter = get_interpreter();
106 let (result, output) = line(&mut interpreter, "Message(\"_\")");
107 is_unit_with_output(&result, &output, "_");
108 }
109
110 #[test]
111 fn core_members_should_be_available() {
112 let mut interpreter = get_interpreter();
113 let (result, output) = line(&mut interpreter, "Length([1, 2, 3])");
114 is_only_value(&result, &output, &Value::Int(3));
115 }
116
117 #[test]
118 fn let_bindings_update_interpreter() {
119 let mut interpreter = get_interpreter();
120 line(&mut interpreter, "let y = 7;")
121 .0
122 .expect("line should succeed");
123 let (result, output) = line(&mut interpreter, "y");
124 is_only_value(&result, &output, &Value::Int(7));
125 }
126
127 #[test]
128 fn let_bindings_can_be_shadowed() {
129 let mut interpreter = get_interpreter();
130
131 let (result, output) = line(&mut interpreter, "let y = 7;");
132 is_only_value(&result, &output, &Value::unit());
133
134 let (result, output) = line(&mut interpreter, "y");
135 is_only_value(&result, &output, &Value::Int(7));
136
137 let (result, output) = line(&mut interpreter, "let y = \"Hello\";");
138 is_only_value(&result, &output, &Value::unit());
139
140 let (result, output) = line(&mut interpreter, "y");
141 is_only_value(&result, &output, &Value::String("Hello".into()));
142 }
143
144 #[test]
145 fn invalid_statements_return_error() {
146 let mut interpreter = get_interpreter();
147
148 let (result, output) = line(&mut interpreter, "let y = 7");
149 is_only_error(
150 &result,
151 &output,
152 &expect![[r#"
153 syntax error: expected `;`, found EOF
154 [line_0] []
155 "#]],
156 );
157
158 let (result, output) = line(&mut interpreter, "y");
159 is_only_error(
160 &result,
161 &output,
162 &expect![[r#"
163 name error: `y` not found
164 [line_1] [y]
165 "#]],
166 );
167 }
168
169 #[test]
170 fn invalid_statements_and_unbound_vars_return_error() {
171 let mut interpreter = get_interpreter();
172
173 let (result, output) = line(&mut interpreter, "let y = x;");
174 is_only_error(
175 &result,
176 &output,
177 &expect![[r#"
178 name error: `x` not found
179 [line_0] [x]
180 type error: insufficient type information to infer type
181 [line_0] [y]
182 "#]],
183 );
184
185 let (result, output) = line(&mut interpreter, "y");
186 is_only_error(
187 &result,
188 &output,
189 &expect![[r#"
190 runtime error: name is not bound
191 [line_1] [y]
192 "#]],
193 );
194 }
195
196 #[test]
197 fn failing_statements_return_early_error() {
198 let mut interpreter = get_interpreter();
199 let (result, output) = line(&mut interpreter, "let y = 7;y/0;y");
200 is_only_error(
201 &result,
202 &output,
203 &expect![[r#"
204 runtime error: division by zero
205 cannot divide by zero [line_0] [0]
206 "#]],
207 );
208 }
209
210 #[test]
211 fn passes_are_run_on_incremental() {
212 let mut interpreter = get_interpreter();
213 let (result, output) = line(
214 &mut interpreter,
215 "within {Message(\"A\");} apply {Message(\"B\");}",
216 );
217 is_unit_with_output(&result, &output, "A\nB\nA");
218 }
219
220 #[test]
221 fn declare_function() {
222 let mut interpreter = get_interpreter();
223 let (result, output) = line(&mut interpreter, "function Foo() : Int { 2 }");
224 is_only_value(&result, &output, &Value::unit());
225 let (result, output) = line(&mut interpreter, "Foo()");
226 is_only_value(&result, &output, &Value::Int(2));
227 }
228
229 #[test]
230 fn invalid_declare_function_and_unbound_call_return_error() {
231 let mut interpreter = get_interpreter();
232 let (result, output) = line(&mut interpreter, "function Foo() : Int { invalid }");
233 is_only_error(
234 &result,
235 &output,
236 &expect![[r#"
237 name error: `invalid` not found
238 [line_0] [invalid]
239 "#]],
240 );
241 let (result, output) = line(&mut interpreter, "Foo()");
242 is_only_error(
243 &result,
244 &output,
245 &expect![[r#"
246 runtime error: name is not bound
247 [line_1] [Foo]
248 "#]],
249 );
250 }
251
252 #[test]
253 fn declare_function_call_same_line() {
254 let mut interpreter = get_interpreter();
255 let (result, output) = line(&mut interpreter, "function Foo() : Int { 2 }; Foo()");
256 is_only_value(&result, &output, &Value::Int(2));
257 }
258
259 #[test]
260 fn let_binding_function_declaration_call_same_line() {
261 let mut interpreter = get_interpreter();
262 let (result, output) = line(
263 &mut interpreter,
264 "let x = 1; function Foo() : Int { 2 }; Foo() + 1",
265 );
266 is_only_value(&result, &output, &Value::Int(3));
267 }
268
269 #[test]
270 fn nested_function() {
271 let mut interpreter = get_interpreter();
272 let (result, output) = line(
273 &mut interpreter,
274 "function Foo() : Int { function Bar() : Int { 1 }; Bar() + 1 }; Foo() + 1",
275 );
276 is_only_value(&result, &output, &Value::Int(3));
277 }
278
279 #[test]
280 fn open_namespace() {
281 let mut interpreter = get_interpreter();
282 let (result, output) = line(&mut interpreter, "import Std.Diagnostics.*;");
283 is_only_value(&result, &output, &Value::unit());
284 let (result, output) = line(&mut interpreter, "DumpMachine()");
285 is_unit_with_output(&result, &output, "STATE:\nNo qubits allocated");
286 }
287
288 #[test]
289 fn open_namespace_call_same_line() {
290 let mut interpreter = get_interpreter();
291 let (result, output) = line(
292 &mut interpreter,
293 "open Microsoft.Quantum.Diagnostics; DumpMachine()",
294 );
295 is_unit_with_output(&result, &output, "STATE:\nNo qubits allocated");
296 }
297
298 #[test]
299 fn declare_namespace_call() {
300 let mut interpreter = get_interpreter();
301 let (result, output) = line(
302 &mut interpreter,
303 "namespace Foo { function Bar() : Int { 5 } }",
304 );
305 is_only_value(&result, &output, &Value::unit());
306 let (result, output) = line(&mut interpreter, "Foo.Bar()");
307 is_only_value(&result, &output, &Value::Int(5));
308 }
309
310 #[test]
311 fn declare_namespace_open_call() {
312 let mut interpreter = get_interpreter();
313 let (result, output) = line(
314 &mut interpreter,
315 "namespace Foo { function Bar() : Int { 5 } }",
316 );
317 is_only_value(&result, &output, &Value::unit());
318 let (result, output) = line(&mut interpreter, "open Foo;");
319 is_only_value(&result, &output, &Value::unit());
320 let (result, output) = line(&mut interpreter, "Bar()");
321 is_only_value(&result, &output, &Value::Int(5));
322 }
323
324 #[test]
325 fn declare_namespace_open_call_same_line() {
326 let mut interpreter = get_interpreter();
327 let (result, output) = line(
328 &mut interpreter,
329 "namespace Foo { function Bar() : Int { 5 } } open Foo; Bar()",
330 );
331 is_only_value(&result, &output, &Value::Int(5));
332 }
333
334 #[test]
335 fn mix_stmts_and_namespace_same_line() {
336 let mut interpreter = get_interpreter();
337 let (result, output) = line(
338 &mut interpreter,
339 "Message(\"before\"); namespace Foo { function Bar() : Int { 5 } } Message(\"after\")",
340 );
341 is_unit_with_output(&result, &output, "before\nafter");
342 }
343
344 #[test]
345 fn global_qubits() {
346 let mut interpreter = get_interpreter();
347 let (result, output) = line(&mut interpreter, "import Std.Diagnostics.*;");
348 is_only_value(&result, &output, &Value::unit());
349 let (result, output) = line(&mut interpreter, "DumpMachine()");
350 is_unit_with_output(&result, &output, "STATE:\nNo qubits allocated");
351 let (result, output) = line(&mut interpreter, "use (q0, qs) = (Qubit(), Qubit[3]);");
352 is_only_value(&result, &output, &Value::unit());
353 let (result, output) = line(&mut interpreter, "DumpMachine()");
354 is_unit_with_output(&result, &output, "STATE:\n|0000⟩: 1+0i");
355 let (result, output) = line(&mut interpreter, "X(q0); X(qs[1]);");
356 is_only_value(&result, &output, &Value::unit());
357 let (result, output) = line(&mut interpreter, "DumpMachine()");
358 is_unit_with_output(&result, &output, "STATE:\n|1010⟩: 1+0i");
359 }
360
361 #[test]
362 fn ambiguous_type_error_in_top_level_stmts() {
363 let mut interpreter = get_interpreter();
364 let (result, output) = line(&mut interpreter, "let x = [];");
365 is_only_error(
366 &result,
367 &output,
368 &expect![[r#"
369 type error: insufficient type information to infer type
370 [line_0] [[]]
371 "#]],
372 );
373 let (result, output) = line(&mut interpreter, "let x = []; let y = [0] + x;");
374 is_only_value(&result, &output, &Value::unit());
375 let (result, output) = line(&mut interpreter, "function Foo() : Unit { let x = []; }");
376 is_only_error(
377 &result,
378 &output,
379 &expect![[r#"
380 type error: insufficient type information to infer type
381 [line_2] [[]]
382 "#]],
383 );
384 }
385
386 #[test]
387 fn resolved_type_persists_across_stmts() {
388 let mut interpreter = get_interpreter();
389 let (result, output) = line(&mut interpreter, "let x = []; let y = [0] + x;");
390 is_only_value(&result, &output, &Value::unit());
391 let (result, output) = line(&mut interpreter, "let z = [0.0] + x;");
392 is_only_error(
393 &result,
394 &output,
395 &expect![[r#"
396 type error: expected Double, found Int
397 [line_1] [x]
398 "#]],
399 );
400 }
401
402 #[test]
403 fn incremental_lambas_work() {
404 let mut interpreter = get_interpreter();
405 let (result, output) = line(&mut interpreter, "let x = 1; let f = (y) -> x + y;");
406 is_only_value(&result, &output, &Value::unit());
407 let (result, output) = line(&mut interpreter, "f(1)");
408 is_only_value(&result, &output, &Value::Int(2));
409 }
410
411 #[test]
412 fn mutability_persists_across_stmts() {
413 let mut interpreter = get_interpreter();
414 let (result, output) = line(
415 &mut interpreter,
416 "mutable x : Int[] = []; let y : Int[] = [];",
417 );
418 is_only_value(&result, &output, &Value::unit());
419 let (result, output) = line(&mut interpreter, "set x += [0];");
420 is_only_value(&result, &output, &Value::unit());
421 let (result, output) = line(&mut interpreter, "set y += [0];");
422 is_only_error(
423 &result,
424 &output,
425 &expect![[r#"
426 cannot update immutable variable
427 [line_2] [y]
428 "#]],
429 );
430 let (result, output) = line(&mut interpreter, "let lam = () -> y + [0];");
431 is_only_value(&result, &output, &Value::unit());
432 let (result, output) = line(&mut interpreter, "let lam = () -> x + [0];");
433 is_only_error(
434 &result,
435 &output,
436 &expect![[r#"
437 lambdas cannot close over mutable variables
438 [line_4] [() -> x + [0]]
439 "#]],
440 );
441 }
442
443 #[test]
444 fn runtime_error_across_lines() {
445 let mut interpreter = get_interpreter();
446 let (result, output) = line(
447 &mut interpreter,
448 "operation Main() : Unit { Microsoft.Quantum.Random.DrawRandomInt(2,1); }",
449 );
450 is_only_value(&result, &output, &Value::unit());
451 let (result, output) = line(&mut interpreter, "Main()");
452 is_only_error(
453 &result,
454 &output,
455 &expect![[r#"
456 runtime error: empty range
457 the range cannot be empty [line_0] [(2,1)]
458 "#]],
459 );
460 }
461
462 #[test]
463 fn compiler_error_across_lines() {
464 let mut interpreter = get_interpreter();
465 let (result, output) = line(
466 &mut interpreter,
467 "namespace Other { operation DumpMachine() : Unit { } }",
468 );
469 is_only_value(&result, &output, &Value::unit());
470 let (result, output) = line(&mut interpreter, "open Other;");
471 is_only_value(&result, &output, &Value::unit());
472 let (result, output) = line(&mut interpreter, "import Std.Diagnostics.*;");
473 is_only_value(&result, &output, &Value::unit());
474 let (result, output) = line(&mut interpreter, "DumpMachine();");
475 is_only_error(
476 &result,
477 &output,
478 &expect![[r#"
479 name error: `DumpMachine` could refer to the item in `Other` or `Microsoft.Quantum.Diagnostics`
480 ambiguous name [line_3] [DumpMachine]
481 found in this namespace [line_1] [Other]
482 and also in this namespace [line_2] [Std.Diagnostics]
483 type error: insufficient type information to infer type
484 [line_3] [DumpMachine()]
485 "#]],
486 );
487 }
488
489 #[test]
490 fn runtime_error_from_stdlib() {
491 let mut interpreter = get_interpreter();
492 let (result, output) = line(&mut interpreter, "use q = Qubit(); CNOT(q,q)");
493 is_only_error(
494 &result,
495 &output,
496 &expect![[r#"
497 runtime error: qubits in invocation are not unique
498 [qsharp-library-source:Std/Intrinsic.qs] [(control, target)]
499 "#]],
500 );
501 }
502
503 #[test]
504 fn items_usable_before_definition() {
505 let mut interpreter = get_interpreter();
506 let (result, output) = line(
507 &mut interpreter,
508 indoc! {r#"
509 function A() : Unit {
510 B();
511 }
512 function B() : Unit {}
513 A()
514 "#},
515 );
516 is_only_value(&result, &output, &Value::unit());
517 }
518
519 #[test]
520 fn items_usable_before_definition_top_level() {
521 let mut interpreter = get_interpreter();
522 let (result, output) = line(
523 &mut interpreter,
524 indoc! {r#"
525 B();
526 function B() : Unit {}
527 "#},
528 );
529 is_only_value(&result, &output, &Value::unit());
530 }
531
532 #[test]
533 fn interpreter_without_sources_has_no_items() {
534 let interpreter = get_interpreter();
535 let items = interpreter.user_globals();
536 assert!(items.is_empty());
537 }
538
539 #[test]
540 fn fragment_without_items_has_no_items() {
541 let mut interpreter = get_interpreter();
542 let (result, output) = line(&mut interpreter, "()");
543 is_only_value(&result, &output, &Value::unit());
544 let items = interpreter.source_globals();
545 assert!(items.is_empty());
546 }
547
548 #[test]
549 fn fragment_defining_items_has_items() {
550 let mut interpreter = get_interpreter();
551 let (result, output) = line(
552 &mut interpreter,
553 indoc! {r#"
554 function Foo() : Int { 2 }
555 function Bar() : Int { 3 }
556 "#},
557 );
558 is_only_value(&result, &output, &Value::unit());
559 let items = interpreter.source_globals();
560 assert_eq!(items.len(), 2);
561 // No namespace for top-level items
562 assert!(items[0].0.is_empty());
563 expect![[r#"
564 "Foo"
565 "#]]
566 .assert_debug_eq(&items[0].1);
567 // No namespace for top-level items
568 assert!(items[1].0.is_empty());
569 expect![[r#"
570 "Bar"
571 "#]]
572 .assert_debug_eq(&items[1].1);
573 }
574
575 #[test]
576 fn fragment_defining_items_with_namespace_has_items() {
577 let mut interpreter = get_interpreter();
578 let (result, output) = line(
579 &mut interpreter,
580 indoc! {r#"
581 namespace Foo {
582 function Bar() : Int { 3 }
583 }
584 "#},
585 );
586 is_only_value(&result, &output, &Value::unit());
587 let items = interpreter.source_globals();
588 assert_eq!(items.len(), 1);
589 expect![[r#"
590 [
591 "Foo",
592 ]
593 "#]]
594 .assert_debug_eq(&items[0].0);
595 expect![[r#"
596 "Bar"
597 "#]]
598 .assert_debug_eq(&items[0].1);
599 }
600
601 #[test]
602 fn fragments_defining_items_add_to_existing_items() {
603 let mut interpreter = get_interpreter();
604 let (result, output) = line(
605 &mut interpreter,
606 indoc! {r#"
607 function Foo() : Int { 2 }
608 function Bar() : Int { 3 }
609 "#},
610 );
611 is_only_value(&result, &output, &Value::unit());
612 let items = interpreter.source_globals();
613 assert_eq!(items.len(), 2);
614 let (result, output) = line(
615 &mut interpreter,
616 indoc! {r#"
617 function Baz() : Int { 4 }
618 function Qux() : Int { 5 }
619 "#},
620 );
621 is_only_value(&result, &output, &Value::unit());
622 let items = interpreter.source_globals();
623 assert_eq!(items.len(), 4);
624 // No namespace for top-level items
625 assert!(items[0].0.is_empty());
626 expect![[r#"
627 "Foo"
628 "#]]
629 .assert_debug_eq(&items[0].1);
630 // No namespace for top-level items
631 assert!(items[1].0.is_empty());
632 expect![[r#"
633 "Bar"
634 "#]]
635 .assert_debug_eq(&items[1].1);
636 // No namespace for top-level items
637 assert!(items[2].0.is_empty());
638 expect![[r#"
639 "Baz"
640 "#]]
641 .assert_debug_eq(&items[2].1);
642 // No namespace for top-level items
643 assert!(items[3].0.is_empty());
644 expect![[r#"
645 "Qux"
646 "#]]
647 .assert_debug_eq(&items[3].1);
648 }
649
650 #[test]
651 fn invoke_callable_without_args_succeeds() {
652 let mut interpreter = get_interpreter();
653 let (result, output) = invoke(
654 &mut interpreter,
655 "Std.Diagnostics.DumpMachine",
656 Value::unit(),
657 );
658 is_unit_with_output(&result, &output, "STATE:\nNo qubits allocated");
659 }
660
661 #[test]
662 fn invoke_callable_with_args_succeeds() {
663 let mut interpreter = get_interpreter();
664 let (result, output) = invoke(
665 &mut interpreter,
666 "Message",
667 Value::String("Hello, World!".into()),
668 );
669 is_unit_with_output(&result, &output, "Hello, World!");
670 }
671
672 #[test]
673 fn invoke_lambda_with_capture_succeeds() {
674 let mut interpreter = get_interpreter();
675 let (result, output) = line(&mut interpreter, "let x = 1; let f = y -> x + y;");
676 is_only_value(&result, &output, &Value::unit());
677 let (result, output) = invoke(&mut interpreter, "f", Value::Int(2));
678 is_only_value(&result, &output, &Value::Int(3));
679 }
680
681 #[test]
682 fn invoke_lambda_with_capture_in_callable_expr_succeeds() {
683 let mut interpreter = get_interpreter();
684 let (result, output) = invoke(
685 &mut interpreter,
686 "{let x = 1; let f = y -> x + y; f}",
687 Value::Int(2),
688 );
689 is_only_value(&result, &output, &Value::Int(3));
690 }
691
692 #[test]
693 fn callables_failing_profile_validation_are_not_registered() {
694 let mut interpreter =
695 get_interpreter_with_capabilities(TargetCapabilityFlags::Adaptive);
696 let (result, output) = line(
697 &mut interpreter,
698 indoc! {r#"
699 operation Foo() : Int { use q = Qubit(); mutable x = 1; if MResetZ(q) == One { set x = 2; } x }
700 "#},
701 );
702 is_only_error(
703 &result,
704 &output,
705 &expect![[r#"
706 cannot use a dynamic integer value
707 [line_0] [set x = 2]
708 cannot use a dynamic integer value
709 [line_0] [x]
710 "#]],
711 );
712 // do something innocuous
713 let (result, output) = line(&mut interpreter, indoc! {r#"Foo()"#});
714 // since the callable wasn't registered, this will return an unbound name error.
715 is_only_error(
716 &result,
717 &output,
718 &expect![[r#"
719 runtime error: name is not bound
720 [line_1] [Foo]
721 "#]],
722 );
723 }
724
725 #[test]
726 fn callables_failing_profile_validation_also_fail_qir_generation() {
727 let mut interpreter =
728 get_interpreter_with_capabilities(TargetCapabilityFlags::Adaptive);
729 let (result, output) = line(
730 &mut interpreter,
731 indoc! {r#"
732 operation Foo() : Int { use q = Qubit(); mutable x = 1; if MResetZ(q) == One { set x = 2; } x }
733 "#},
734 );
735 is_only_error(
736 &result,
737 &output,
738 &expect![[r#"
739 cannot use a dynamic integer value
740 [line_0] [set x = 2]
741 cannot use a dynamic integer value
742 [line_0] [x]
743 "#]],
744 );
745 let res = interpreter.qirgen("{Foo();}");
746 expect![[r#"
747 Err(
748 [
749 PartialEvaluation(
750 WithSource {
751 sources: [
752 Source {
753 name: "<entry>",
754 contents: "{Foo();}",
755 offset: 97,
756 },
757 ],
758 error: EvaluationFailed(
759 "name is not bound",
760 PackageSpan {
761 package: PackageId(
762 3,
763 ),
764 span: Span {
765 lo: 98,
766 hi: 101,
767 },
768 },
769 ),
770 },
771 ),
772 ],
773 )
774 "#]]
775 .assert_debug_eq(&res);
776 }
777
778 #[test]
779 fn once_rca_validation_fails_following_calls_do_not_fail() {
780 let mut interpreter =
781 get_interpreter_with_capabilities(TargetCapabilityFlags::Adaptive);
782 let (result, output) = line(
783 &mut interpreter,
784 indoc! {r#"
785 operation Foo() : Int { use q = Qubit(); mutable x = 1; if MResetZ(q) == One { set x = 2; } x }
786 "#},
787 );
788 is_only_error(
789 &result,
790 &output,
791 &expect![[r#"
792 cannot use a dynamic integer value
793 [line_0] [set x = 2]
794 cannot use a dynamic integer value
795 [line_0] [x]
796 "#]],
797 );
798 // do something innocuous
799 let (result, output) = line(
800 &mut interpreter,
801 indoc! {r#"
802 let y = 7;
803 "#},
804 );
805 is_only_value(&result, &output, &Value::unit());
806 }
807
808 #[test]
809 fn namespace_usable_before_definition() {
810 let mut interpreter = get_interpreter();
811 let (result, output) = line(
812 &mut interpreter,
813 indoc! {r#"
814 A.B();
815 namespace A {
816 function B() : Unit {}
817 }
818 "#},
819 );
820 is_only_value(&result, &output, &Value::unit());
821 }
822
823 #[test]
824 fn mutually_recursive_namespaces_work() {
825 let mut interpreter = get_interpreter();
826 let (result, output) = line(
827 &mut interpreter,
828 indoc! {r#"
829 A.B();
830 namespace A {
831 open C;
832 function B() : Unit {
833 D();
834 }
835 function E() : Unit {}
836 }
837 namespace C {
838 open A;
839 function D() : Unit {
840 E();
841 }
842 }
843 "#},
844 );
845 is_only_value(&result, &output, &Value::unit());
846 }
847
848 #[test]
849 fn local_var_valid_after_item_definition() {
850 let mut interpreter = get_interpreter_with_capabilities(TargetCapabilityFlags::empty());
851 let (result, output) = line(&mut interpreter, "let a = 1;");
852 is_only_value(&result, &output, &Value::unit());
853 let (result, output) = line(&mut interpreter, "a");
854 is_only_value(&result, &output, &Value::Int(1));
855 let (result, output) = line(
856 &mut interpreter,
857 "function B() : Int { let inner_b = 3; inner_b }",
858 );
859 is_only_value(&result, &output, &Value::unit());
860 let (result, output) = line(&mut interpreter, "B()");
861 is_only_value(&result, &output, &Value::Int(3));
862 let (result, output) = line(&mut interpreter, "let b = 2;");
863 is_only_value(&result, &output, &Value::unit());
864 let (result, output) = line(&mut interpreter, "b");
865 is_only_value(&result, &output, &Value::Int(2));
866 let (result, output) = line(&mut interpreter, "a");
867 is_only_value(&result, &output, &Value::Int(1));
868 let (result, output) = line(&mut interpreter, "B()");
869 is_only_value(&result, &output, &Value::Int(3));
870 }
871
872 #[test]
873 fn base_qirgen() {
874 let mut interpreter = get_interpreter_with_capabilities(TargetCapabilityFlags::empty());
875 let (result, output) = line(
876 &mut interpreter,
877 indoc! {"operation Foo() : Result { use q = Qubit(); let r = M(q); Reset(q); return r; } "},
878 );
879 is_only_value(&result, &output, &Value::unit());
880 let res = interpreter.qirgen("Foo()").expect("expected success");
881 expect![[r#"
882 %Result = type opaque
883 %Qubit = type opaque
884
885 define void @ENTRYPOINT__main() #0 {
886 block_0:
887 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
888 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 0 to %Qubit*))
889 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
890 call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
891 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
892 ret void
893 }
894
895 declare void @__quantum__qis__h__body(%Qubit*)
896
897 declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
898
899 declare void @__quantum__rt__result_record_output(%Result*, i8*)
900
901 declare void @__quantum__qis__m__body(%Qubit*, %Result*) #1
902
903 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="2" "required_num_results"="1" }
904 attributes #1 = { "irreversible" }
905
906 ; module flags
907
908 !llvm.module.flags = !{!0, !1, !2, !3}
909
910 !0 = !{i32 1, !"qir_major_version", i32 1}
911 !1 = !{i32 7, !"qir_minor_version", i32 0}
912 !2 = !{i32 1, !"dynamic_qubit_management", i1 false}
913 !3 = !{i32 1, !"dynamic_result_management", i1 false}
914 "#]].assert_eq(&res);
915 }
916
917 #[test]
918 fn adaptive_qirgen() {
919 let mut interpreter = get_interpreter_with_capabilities(
920 TargetCapabilityFlags::Adaptive
921 | TargetCapabilityFlags::QubitReset
922 | TargetCapabilityFlags::IntegerComputations,
923 );
924 let (result, output) = line(
925 &mut interpreter,
926 indoc! {r#"
927 namespace Test {
928 import Std.Math.*;
929 open QIR.Intrinsic;
930 @EntryPoint()
931 operation Main() : Result {
932 use q = Qubit();
933 let pi_over_2 = 4.0 / 2.0;
934 __quantum__qis__rz__body(pi_over_2, q);
935 mutable some_angle = ArcSin(0.0);
936 __quantum__qis__rz__body(some_angle, q);
937 set some_angle = ArcCos(-1.0) / PI();
938 __quantum__qis__rz__body(some_angle, q);
939 __quantum__qis__mresetz__body(q)
940 }
941 }"#
942 },
943 );
944 is_only_value(&result, &output, &Value::unit());
945 let res = interpreter.qirgen("Test.Main()").expect("expected success");
946 expect![[r#"
947 %Result = type opaque
948 %Qubit = type opaque
949
950 define void @ENTRYPOINT__main() #0 {
951 block_0:
952 call void @__quantum__qis__rz__body(double 2.0, %Qubit* inttoptr (i64 0 to %Qubit*))
953 call void @__quantum__qis__rz__body(double 0.0, %Qubit* inttoptr (i64 0 to %Qubit*))
954 call void @__quantum__qis__rz__body(double 1.0, %Qubit* inttoptr (i64 0 to %Qubit*))
955 call void @__quantum__qis__mresetz__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
956 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
957 ret void
958 }
959
960 declare void @__quantum__qis__rz__body(double, %Qubit*)
961
962 declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*) #1
963
964 declare void @__quantum__rt__result_record_output(%Result*, i8*)
965
966 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="1" }
967 attributes #1 = { "irreversible" }
968
969 ; module flags
970
971 !llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10}
972
973 !0 = !{i32 1, !"qir_major_version", i32 1}
974 !1 = !{i32 7, !"qir_minor_version", i32 0}
975 !2 = !{i32 1, !"dynamic_qubit_management", i1 false}
976 !3 = !{i32 1, !"dynamic_result_management", i1 false}
977 !4 = !{i32 1, !"classical_ints", i1 true}
978 !5 = !{i32 1, !"qubit_resetting", i1 true}
979 !6 = !{i32 1, !"classical_floats", i1 false}
980 !7 = !{i32 1, !"backwards_branching", i1 false}
981 !8 = !{i32 1, !"classical_fixed_points", i1 false}
982 !9 = !{i32 1, !"user_functions", i1 false}
983 !10 = !{i32 1, !"multiple_target_branching", i1 false}
984 "#]]
985 .assert_eq(&res);
986 }
987
988 #[test]
989 fn adaptive_qirgen_nested_output_types() {
990 let mut interpreter = get_interpreter_with_capabilities(
991 TargetCapabilityFlags::Adaptive | TargetCapabilityFlags::QubitReset,
992 );
993 let (result, output) = line(
994 &mut interpreter,
995 indoc! {r#"
996 namespace Test {
997 open QIR.Intrinsic;
998 @EntryPoint()
999 operation Main() : (Result, (Bool, Bool)) {
1000 use q = Qubit();
1001 let r = __quantum__qis__mresetz__body(q);
1002 (r, (r == One, r == Zero))
1003 }
1004 }"#
1005 },
1006 );
1007 is_only_value(&result, &output, &Value::unit());
1008 let res = interpreter.qirgen("Test.Main()").expect("expected success");
1009 expect![[r#"
1010 %Result = type opaque
1011 %Qubit = type opaque
1012
1013 define void @ENTRYPOINT__main() #0 {
1014 block_0:
1015 call void @__quantum__qis__mresetz__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
1016 %var_0 = call i1 @__quantum__qis__read_result__body(%Result* inttoptr (i64 0 to %Result*))
1017 %var_2 = call i1 @__quantum__qis__read_result__body(%Result* inttoptr (i64 0 to %Result*))
1018 %var_3 = icmp eq i1 %var_2, false
1019 call void @__quantum__rt__tuple_record_output(i64 2, i8* null)
1020 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
1021 call void @__quantum__rt__tuple_record_output(i64 2, i8* null)
1022 call void @__quantum__rt__bool_record_output(i1 %var_0, i8* null)
1023 call void @__quantum__rt__bool_record_output(i1 %var_3, i8* null)
1024 ret void
1025 }
1026
1027 declare void @__quantum__qis__mresetz__body(%Qubit*, %Result*) #1
1028
1029 declare i1 @__quantum__qis__read_result__body(%Result*)
1030
1031 declare void @__quantum__rt__tuple_record_output(i64, i8*)
1032
1033 declare void @__quantum__rt__result_record_output(%Result*, i8*)
1034
1035 declare void @__quantum__rt__bool_record_output(i1, i8*)
1036
1037 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="1" }
1038 attributes #1 = { "irreversible" }
1039
1040 ; module flags
1041
1042 !llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10}
1043
1044 !0 = !{i32 1, !"qir_major_version", i32 1}
1045 !1 = !{i32 7, !"qir_minor_version", i32 0}
1046 !2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1047 !3 = !{i32 1, !"dynamic_result_management", i1 false}
1048 !4 = !{i32 1, !"qubit_resetting", i1 true}
1049 !5 = !{i32 1, !"classical_ints", i1 false}
1050 !6 = !{i32 1, !"classical_floats", i1 false}
1051 !7 = !{i32 1, !"backwards_branching", i1 false}
1052 !8 = !{i32 1, !"classical_fixed_points", i1 false}
1053 !9 = !{i32 1, !"user_functions", i1 false}
1054 !10 = !{i32 1, !"multiple_target_branching", i1 false}
1055 "#]]
1056 .assert_eq(&res);
1057 }
1058
1059 #[test]
1060 fn adaptive_qirgen_fails_when_entry_expr_does_not_match_profile() {
1061 let mut interpreter =
1062 get_interpreter_with_capabilities(TargetCapabilityFlags::Adaptive);
1063 let (result, output) = line(
1064 &mut interpreter,
1065 indoc! {r#"
1066 use q = Qubit();
1067 mutable x = 1;
1068 "#
1069 },
1070 );
1071 is_only_value(&result, &output, &Value::unit());
1072 let res = interpreter
1073 .qirgen("if M(q) == One { set x = 2; }")
1074 .expect_err("expected error");
1075 is_error(
1076 &res,
1077 &expect![[r#"
1078 cannot use a dynamic integer value
1079 [<entry>] [set x = 2]
1080 "#]],
1081 );
1082 }
1083
1084 #[test]
1085 fn qirgen_entry_expr_in_block() {
1086 let mut interpreter = get_interpreter_with_capabilities(TargetCapabilityFlags::empty());
1087 let (result, output) = line(
1088 &mut interpreter,
1089 indoc! {"operation Foo() : Result { use q = Qubit(); let r = M(q); Reset(q); return r; } "},
1090 );
1091 is_only_value(&result, &output, &Value::unit());
1092 let res = interpreter.qirgen("{Foo()}").expect("expected success");
1093 expect![[r#"
1094 %Result = type opaque
1095 %Qubit = type opaque
1096
1097 define void @ENTRYPOINT__main() #0 {
1098 block_0:
1099 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
1100 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 0 to %Qubit*))
1101 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
1102 call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
1103 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
1104 ret void
1105 }
1106
1107 declare void @__quantum__qis__h__body(%Qubit*)
1108
1109 declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
1110
1111 declare void @__quantum__rt__result_record_output(%Result*, i8*)
1112
1113 declare void @__quantum__qis__m__body(%Qubit*, %Result*) #1
1114
1115 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="2" "required_num_results"="1" }
1116 attributes #1 = { "irreversible" }
1117
1118 ; module flags
1119
1120 !llvm.module.flags = !{!0, !1, !2, !3}
1121
1122 !0 = !{i32 1, !"qir_major_version", i32 1}
1123 !1 = !{i32 7, !"qir_minor_version", i32 0}
1124 !2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1125 !3 = !{i32 1, !"dynamic_result_management", i1 false}
1126 "#]].assert_eq(&res);
1127 }
1128
1129 #[test]
1130 fn qirgen_entry_expr_defines_operation() {
1131 let mut interpreter = get_interpreter_with_capabilities(TargetCapabilityFlags::empty());
1132
1133 let (result, output) = line(
1134 &mut interpreter,
1135 indoc! {"operation Foo() : Result { use q = Qubit(); let r = M(q); Reset(q); return r; } "},
1136 );
1137 is_only_value(&result, &output, &Value::unit());
1138 let res = interpreter
1139 .qirgen("{operation Bar() : Unit {}; Foo()}")
1140 .expect("expected success");
1141 expect![[r#"
1142 %Result = type opaque
1143 %Qubit = type opaque
1144
1145 define void @ENTRYPOINT__main() #0 {
1146 block_0:
1147 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
1148 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 0 to %Qubit*))
1149 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
1150 call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
1151 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
1152 ret void
1153 }
1154
1155 declare void @__quantum__qis__h__body(%Qubit*)
1156
1157 declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
1158
1159 declare void @__quantum__rt__result_record_output(%Result*, i8*)
1160
1161 declare void @__quantum__qis__m__body(%Qubit*, %Result*) #1
1162
1163 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="2" "required_num_results"="1" }
1164 attributes #1 = { "irreversible" }
1165
1166 ; module flags
1167
1168 !llvm.module.flags = !{!0, !1, !2, !3}
1169
1170 !0 = !{i32 1, !"qir_major_version", i32 1}
1171 !1 = !{i32 7, !"qir_minor_version", i32 0}
1172 !2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1173 !3 = !{i32 1, !"dynamic_result_management", i1 false}
1174 "#]].assert_eq(&res);
1175
1176 // Operation should not be visible from global scope
1177 let (result, output) = line(&mut interpreter, indoc! {"Bar()"});
1178 is_only_error(
1179 &result,
1180 &output,
1181 &expect![[r#"
1182 name error: `Bar` not found
1183 [line_1] [Bar]
1184 type error: insufficient type information to infer type
1185 [line_1] [Bar()]
1186 "#]],
1187 );
1188 }
1189
1190 #[test]
1191 fn qirgen_multiple_exprs_parse_fail() {
1192 let mut interpreter = get_interpreter_with_capabilities(TargetCapabilityFlags::empty());
1193 let (result, output) = line(
1194 &mut interpreter,
1195 indoc! {"operation Foo() : Result { use q = Qubit(); let r = M(q); Reset(q); return r; } "},
1196 );
1197 is_only_value(&result, &output, &Value::unit());
1198 let res = interpreter
1199 .qirgen("Foo(); operation Bar() : Unit {}; Foo()")
1200 .expect_err("expected error");
1201 is_error(
1202 &res,
1203 &expect![[r#"
1204 syntax error: expected EOF, found `;`
1205 [<entry>] [;]
1206 "#]],
1207 );
1208 }
1209
1210 #[test]
1211 fn qirgen_entry_expr_defines_operation_then_more_operations() {
1212 let mut interpreter = get_interpreter_with_capabilities(TargetCapabilityFlags::empty());
1213 let (result, output) = line(
1214 &mut interpreter,
1215 indoc! {"operation Foo() : Result { use q = Qubit(); let r = M(q); Reset(q); return r; } "},
1216 );
1217 is_only_value(&result, &output, &Value::unit());
1218 let res = interpreter
1219 .qirgen("{operation Bar() : Unit {}; Foo()}")
1220 .expect("expected success");
1221 expect![[r#"
1222 %Result = type opaque
1223 %Qubit = type opaque
1224
1225 define void @ENTRYPOINT__main() #0 {
1226 block_0:
1227 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
1228 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 0 to %Qubit*))
1229 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
1230 call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
1231 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
1232 ret void
1233 }
1234
1235 declare void @__quantum__qis__h__body(%Qubit*)
1236
1237 declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
1238
1239 declare void @__quantum__rt__result_record_output(%Result*, i8*)
1240
1241 declare void @__quantum__qis__m__body(%Qubit*, %Result*) #1
1242
1243 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="2" "required_num_results"="1" }
1244 attributes #1 = { "irreversible" }
1245
1246 ; module flags
1247
1248 !llvm.module.flags = !{!0, !1, !2, !3}
1249
1250 !0 = !{i32 1, !"qir_major_version", i32 1}
1251 !1 = !{i32 7, !"qir_minor_version", i32 0}
1252 !2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1253 !3 = !{i32 1, !"dynamic_result_management", i1 false}
1254 "#]].assert_eq(&res);
1255
1256 let (result, output) = line(
1257 &mut interpreter,
1258 indoc! {"operation Baz() : Result { use q = Qubit(); let r = M(q); Reset(q); return r; } "},
1259 );
1260 is_only_value(&result, &output, &Value::unit());
1261
1262 let (result, output) = line(&mut interpreter, indoc! {"Bar()"});
1263 is_only_error(
1264 &result,
1265 &output,
1266 &expect![[r#"
1267 name error: `Bar` not found
1268 [line_2] [Bar]
1269 type error: insufficient type information to infer type
1270 [line_2] [Bar()]
1271 "#]],
1272 );
1273 }
1274
1275 #[test]
1276 fn qirgen_define_operation_use_it() {
1277 let mut interpreter = get_interpreter_with_capabilities(TargetCapabilityFlags::empty());
1278 let res = interpreter
1279 .qirgen("{ operation Foo() : Result { use q = Qubit(); let r = M(q); Reset(q); return r; }; Foo() }")
1280 .expect("expected success");
1281 expect![[r#"
1282 %Result = type opaque
1283 %Qubit = type opaque
1284
1285 define void @ENTRYPOINT__main() #0 {
1286 block_0:
1287 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
1288 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 0 to %Qubit*))
1289 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
1290 call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
1291 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
1292 ret void
1293 }
1294
1295 declare void @__quantum__qis__h__body(%Qubit*)
1296
1297 declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
1298
1299 declare void @__quantum__rt__result_record_output(%Result*, i8*)
1300
1301 declare void @__quantum__qis__m__body(%Qubit*, %Result*) #1
1302
1303 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="2" "required_num_results"="1" }
1304 attributes #1 = { "irreversible" }
1305
1306 ; module flags
1307
1308 !llvm.module.flags = !{!0, !1, !2, !3}
1309
1310 !0 = !{i32 1, !"qir_major_version", i32 1}
1311 !1 = !{i32 7, !"qir_minor_version", i32 0}
1312 !2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1313 !3 = !{i32 1, !"dynamic_result_management", i1 false}
1314 "#]].assert_eq(&res);
1315 }
1316
1317 #[test]
1318 fn qirgen_entry_expr_profile_incompatible() {
1319 let mut interpreter = get_interpreter_with_capabilities(TargetCapabilityFlags::empty());
1320 let res = interpreter
1321 .qirgen("1")
1322 .expect_err("expected qirgen to fail");
1323 is_error(
1324 &res,
1325 &expect![[r#"
1326 cannot use an integer value as an output
1327 [<entry>] [1]
1328 "#]],
1329 );
1330 }
1331
1332 #[test]
1333 fn run_with_shots() {
1334 let mut interpreter = get_interpreter();
1335 let (result, output) = line(&mut interpreter, "operation Foo(qs : Qubit[]) : Unit { Microsoft.Quantum.Diagnostics.DumpMachine(); }");
1336 is_only_value(&result, &output, &Value::unit());
1337 for _ in 0..4 {
1338 let (results, output) = run(&mut interpreter, "{use qs = Qubit[2]; Foo(qs)}");
1339 is_unit_with_output(&results, &output, "STATE:\n|00⟩: 1+0i");
1340 }
1341 }
1342
1343 #[test]
1344 fn run_parse_error() {
1345 let mut interpreter = get_interpreter();
1346 let (results, _) = run(&mut interpreter, "Foo)");
1347 results.expect_err("run() should fail");
1348 }
1349
1350 #[test]
1351 fn run_compile_error() {
1352 let mut interpreter = get_interpreter();
1353 let (results, _) = run(&mut interpreter, "Foo()");
1354 results.expect_err("run() should fail");
1355 }
1356
1357 #[test]
1358 fn run_multiple_statements_with_return_value() {
1359 let mut interpreter = get_interpreter();
1360 let (result, output) = line(&mut interpreter, "operation Foo() : Int { 1 }");
1361 is_only_value(&result, &output, &Value::unit());
1362 let (result, output) = line(&mut interpreter, "operation Bar() : Int { 2 }");
1363 is_only_value(&result, &output, &Value::unit());
1364 let (result, output) = run(&mut interpreter, "{ Foo(); Bar() }");
1365 is_only_value(&result, &output, &Value::Int(2));
1366 }
1367
1368 #[test]
1369 fn run_runtime_failure() {
1370 let mut interpreter = get_interpreter();
1371 let (result, output) = line(
1372 &mut interpreter,
1373 r#"operation Foo() : Int { fail "failed" }"#,
1374 );
1375 is_only_value(&result, &output, &Value::unit());
1376 for _ in 0..1 {
1377 let (result, output) = run(&mut interpreter, "Foo()");
1378 is_only_error(
1379 &result,
1380 &output,
1381 &expect![[r#"
1382 runtime error: program failed: failed
1383 explicit fail [line_0] [fail "failed"]
1384 "#]],
1385 );
1386 }
1387 }
1388
1389 #[test]
1390 fn run_output_merged() {
1391 let mut interpreter = get_interpreter();
1392 let (result, output) = line(
1393 &mut interpreter,
1394 r#"operation Foo() : Unit { Message("hello!") }"#,
1395 );
1396 is_only_value(&result, &output, &Value::unit());
1397 for _ in 0..4 {
1398 let (result, output) = run(&mut interpreter, "Foo()");
1399 is_unit_with_output(&result, &output, "hello!");
1400 }
1401 }
1402
1403 #[test]
1404 fn base_prof_non_result_return() {
1405 let mut interpreter = get_interpreter_with_capabilities(TargetCapabilityFlags::empty());
1406 let (result, output) = line(&mut interpreter, "123");
1407 is_only_value(&result, &output, &Value::Int(123));
1408 }
1409 }
1410
1411 fn get_interpreter() -> Interpreter {
1412 let (std_id, store) =
1413 crate::compile::package_store_with_stdlib(TargetCapabilityFlags::all());
1414 let dependencies = &[(std_id, None)];
1415 Interpreter::new(
1416 SourceMap::default(),
1417 PackageType::Lib,
1418 TargetCapabilityFlags::all(),
1419 LanguageFeatures::default(),
1420 store,
1421 dependencies,
1422 )
1423 .expect("interpreter should be created")
1424 }
1425
1426 fn get_interpreter_with_capabilities(capabilities: TargetCapabilityFlags) -> Interpreter {
1427 let (std_id, store) = crate::compile::package_store_with_stdlib(capabilities);
1428 let dependencies = &[(std_id, None)];
1429 Interpreter::new(
1430 SourceMap::default(),
1431 PackageType::Lib,
1432 capabilities,
1433 LanguageFeatures::default(),
1434 store,
1435 dependencies,
1436 )
1437 .expect("interpreter should be created")
1438 }
1439
1440 fn is_only_value(result: &InterpretResult, output: &str, value: &Value) {
1441 assert_eq!("", output);
1442
1443 match result {
1444 Ok(v) => assert_eq!(value, v),
1445 Err(e) => panic!("Expected {value:?}, got {e:?}"),
1446 }
1447 }
1448
1449 fn is_unit_with_output_eval_entry(
1450 result: &InterpretResult,
1451 output: &str,
1452 expected_output: &str,
1453 ) {
1454 assert_eq!(expected_output, output);
1455
1456 match result {
1457 Ok(value) => assert_eq!(Value::unit(), *value),
1458 Err(e) => panic!("Expected unit value, got {e:?}"),
1459 }
1460 }
1461
1462 fn is_unit_with_output(result: &InterpretResult, output: &str, expected_output: &str) {
1463 assert_eq!(expected_output, output);
1464
1465 match result {
1466 Ok(value) => assert_eq!(Value::unit(), *value),
1467 Err(e) => panic!("Expected unit value, got {e:?}"),
1468 }
1469 }
1470
1471 fn is_only_error<E>(result: &Result<Value, Vec<E>>, output: &str, expected_errors: &Expect)
1472 where
1473 E: Diagnostic,
1474 {
1475 assert_eq!("", output);
1476
1477 match result {
1478 Ok(value) => panic!("Expected error , got {value:?}"),
1479 Err(errors) => is_error(errors, expected_errors),
1480 }
1481 }
1482
1483 fn is_error<E>(errors: &Vec<E>, expected_errors: &Expect)
1484 where
1485 E: Diagnostic,
1486 {
1487 let mut actual = String::new();
1488 for error in errors {
1489 write!(actual, "{error}").expect("writing should succeed");
1490 for s in iter::successors(error.source(), |&s| s.source()) {
1491 write!(actual, ": {s}").expect("writing should succeed");
1492 }
1493 for label in error.labels().into_iter().flatten() {
1494 let span = error
1495 .source_code()
1496 .expect("expected valid source code")
1497 .read_span(label.inner(), 0, 0)
1498 .expect("expected to be able to read span");
1499
1500 write!(
1501 actual,
1502 "\n {} [{}] [{}]",
1503 label.label().unwrap_or(""),
1504 span.name().expect("expected source file name"),
1505 from_utf8(span.data()).expect("expected valid utf-8 string"),
1506 )
1507 .expect("writing should succeed");
1508 }
1509 writeln!(actual).expect("writing should succeed");
1510 }
1511
1512 expected_errors.assert_eq(&actual);
1513 }
1514
1515 #[cfg(test)]
1516 mod with_sources {
1517 use std::{sync::Arc, vec};
1518
1519 use super::*;
1520 use crate::interpret::Debugger;
1521 use crate::line_column::Encoding;
1522 use expect_test::expect;
1523 use indoc::indoc;
1524
1525 use qsc_ast::ast::{
1526 Expr, ExprKind, NodeId, Package, Path, PathKind, Stmt, StmtKind, TopLevelNode,
1527 };
1528 use qsc_data_structures::span::Span;
1529 use qsc_frontend::compile::SourceMap;
1530 use qsc_passes::PackageType;
1531
1532 #[test]
1533 fn entry_expr_is_executed() {
1534 let source = indoc! { r#"
1535 namespace Test {
1536 @EntryPoint()
1537 operation Main() : Unit {
1538 Message("hello there...")
1539 }
1540 }"#};
1541
1542 let sources = SourceMap::new([("test".into(), source.into())], None);
1543 let (std_id, store) =
1544 crate::compile::package_store_with_stdlib(TargetCapabilityFlags::all());
1545 let mut interpreter = Interpreter::new(
1546 sources,
1547 PackageType::Exe,
1548 TargetCapabilityFlags::all(),
1549 LanguageFeatures::default(),
1550 store,
1551 &[(std_id, None)],
1552 )
1553 .expect("interpreter should be created");
1554
1555 let (result, output) = entry(&mut interpreter);
1556 is_unit_with_output_eval_entry(&result, &output, "hello there...");
1557 }
1558
1559 #[test]
1560 fn errors_returned_if_sources_do_not_match_profile() {
1561 let source = indoc! { r#"
1562 namespace A { operation Test() : Double { use q = Qubit(); mutable x = 1.0; if MResetZ(q) == One { set x = 2.0; } x } }"#};
1563
1564 let sources = SourceMap::new([("test".into(), source.into())], Some("A.Test()".into()));
1565 let (std_id, store) =
1566 crate::compile::package_store_with_stdlib(TargetCapabilityFlags::all());
1567 let result = Interpreter::new(
1568 sources,
1569 PackageType::Exe,
1570 TargetCapabilityFlags::Adaptive
1571 | TargetCapabilityFlags::IntegerComputations
1572 | TargetCapabilityFlags::QubitReset,
1573 LanguageFeatures::default(),
1574 store,
1575 &[(std_id, None)],
1576 );
1577
1578 match result {
1579 Ok(_) => panic!("Expected error, got interpreter."),
1580 Err(errors) => is_error(
1581 &errors,
1582 &expect![[r#"
1583 cannot use a dynamic double value
1584 [<entry>] [A.Test()]
1585 cannot use a double value as an output
1586 [<entry>] [A.Test()]
1587 cannot use a dynamic double value
1588 [test] [set x = 2.0]
1589 cannot use a dynamic double value
1590 [test] [x]
1591 "#]],
1592 ),
1593 }
1594 }
1595
1596 #[test]
1597 fn stdlib_members_can_be_accessed_from_sources() {
1598 let source = indoc! { r#"
1599 namespace Test {
1600 operation Main() : Unit {
1601 Message("hello there...")
1602 }
1603 }"#};
1604
1605 let sources = SourceMap::new([("test".into(), source.into())], None);
1606 let (std_id, store) =
1607 crate::compile::package_store_with_stdlib(TargetCapabilityFlags::all());
1608 let dependencies = &[(std_id, None)];
1609 let mut interpreter = Interpreter::new(
1610 sources,
1611 PackageType::Lib,
1612 TargetCapabilityFlags::all(),
1613 LanguageFeatures::default(),
1614 store,
1615 dependencies,
1616 )
1617 .expect("interpreter should be created");
1618
1619 let (result, output) = line(&mut interpreter, "Test.Main()");
1620 is_unit_with_output(&result, &output, "hello there...");
1621 }
1622
1623 #[test]
1624 fn members_from_namespaced_sources_are_in_context() {
1625 let source = indoc! { r#"
1626 namespace Test {
1627 function Hello() : String {
1628 "hello there..."
1629 }
1630
1631 operation Main() : String {
1632 Hello()
1633 }
1634 }"#};
1635
1636 let sources = SourceMap::new([("test".into(), source.into())], None);
1637 let store = crate::PackageStore::new(crate::compile::core());
1638 let mut interpreter = Interpreter::new(
1639 sources,
1640 PackageType::Lib,
1641 TargetCapabilityFlags::all(),
1642 LanguageFeatures::default(),
1643 store,
1644 &[],
1645 )
1646 .expect("interpreter should be created");
1647
1648 let (result, output) = line(&mut interpreter, "Test.Hello()");
1649 is_only_value(&result, &output, &Value::String("hello there...".into()));
1650 let (result, output) = line(&mut interpreter, "Test.Main()");
1651 is_only_value(&result, &output, &Value::String("hello there...".into()));
1652 }
1653
1654 #[test]
1655 fn multiple_files_are_loaded_from_sources_into_eval_context() {
1656 let sources: [(Arc<str>, Arc<str>); 2] = [
1657 (
1658 "a.qs".into(),
1659 r#"
1660 namespace Test {
1661 function Hello() : String {
1662 "hello there..."
1663 }
1664 }"#
1665 .into(),
1666 ),
1667 (
1668 "b.qs".into(),
1669 r#"
1670 namespace Test2 {
1671 open Test;
1672 @EntryPoint()
1673 operation Main() : String {
1674 Hello();
1675 Hello()
1676 }
1677 }"#
1678 .into(),
1679 ),
1680 ];
1681
1682 let sources = SourceMap::new(sources, None);
1683 let store = crate::PackageStore::new(crate::compile::core());
1684 let debugger = Debugger::new(
1685 sources,
1686 TargetCapabilityFlags::all(),
1687 Encoding::Utf8,
1688 LanguageFeatures::default(),
1689 store,
1690 &[],
1691 )
1692 .expect("debugger should be created");
1693 let bps = debugger.get_breakpoints("a.qs");
1694 assert_eq!(1, bps.len());
1695 let bps = debugger.get_breakpoints("b.qs");
1696 assert_eq!(2, bps.len());
1697 }
1698
1699 #[test]
1700 fn debugger_simple_execution_succeeds() {
1701 let source = indoc! { r#"
1702 namespace Test {
1703 function Hello() : Unit {
1704 Message("hello there...");
1705 }
1706
1707 @EntryPoint()
1708 operation Main() : Unit {
1709 Hello()
1710 }
1711 }"#};
1712
1713 let sources = SourceMap::new([("test".into(), source.into())], None);
1714 let (std_id, store) =
1715 crate::compile::package_store_with_stdlib(TargetCapabilityFlags::all());
1716 let mut debugger = Debugger::new(
1717 sources,
1718 TargetCapabilityFlags::all(),
1719 Encoding::Utf8,
1720 LanguageFeatures::default(),
1721 store,
1722 &[(std_id, None)],
1723 )
1724 .expect("debugger should be created");
1725 let (result, output) = entry(&mut debugger.interpreter);
1726 is_unit_with_output_eval_entry(&result, &output, "hello there...");
1727 }
1728
1729 #[test]
1730 fn debugger_execution_with_call_to_library_succeeds() {
1731 let source = indoc! { r#"
1732 namespace Test {
1733 import Std.Math.*;
1734 @EntryPoint()
1735 operation Main() : Int {
1736 Binom(31, 7)
1737 }
1738 }"#};
1739
1740 let sources = SourceMap::new([("test".into(), source.into())], None);
1741 let (std_id, store) =
1742 crate::compile::package_store_with_stdlib(TargetCapabilityFlags::all());
1743 let mut debugger = Debugger::new(
1744 sources,
1745 TargetCapabilityFlags::all(),
1746 Encoding::Utf8,
1747 LanguageFeatures::default(),
1748 store,
1749 &[(std_id, None)],
1750 )
1751 .expect("debugger should be created");
1752 let (result, output) = entry(&mut debugger.interpreter);
1753 is_only_value(&result, &output, &Value::Int(2_629_575));
1754 }
1755
1756 #[test]
1757 fn debugger_execution_with_early_return_succeeds() {
1758 let source = indoc! { r#"
1759 namespace Test {
1760 import Std.Arrays.*;
1761
1762 operation Max20(i : Int) : Int {
1763 if (i > 20) {
1764 return 20;
1765 }
1766 return i;
1767 }
1768
1769 @EntryPoint()
1770 operation Main() : Int[] {
1771 ForEach(Max20, [10, 20, 30, 40, 50])
1772 }
1773 }"#};
1774
1775 let sources = SourceMap::new([("test".into(), source.into())], None);
1776 let (std_id, store) =
1777 crate::compile::package_store_with_stdlib(TargetCapabilityFlags::all());
1778 let mut debugger = Debugger::new(
1779 sources,
1780 TargetCapabilityFlags::all(),
1781 Encoding::Utf8,
1782 LanguageFeatures::default(),
1783 store,
1784 &[(std_id, None)],
1785 )
1786 .expect("debugger should be created");
1787
1788 let (result, output) = entry(&mut debugger.interpreter);
1789 is_only_value(
1790 &result,
1791 &output,
1792 &Value::Array(
1793 vec![
1794 Value::Int(10),
1795 Value::Int(20),
1796 Value::Int(20),
1797 Value::Int(20),
1798 Value::Int(20),
1799 ]
1800 .into(),
1801 ),
1802 );
1803 }
1804
1805 #[test]
1806 fn multiple_namespaces_are_loaded_from_sources_into_eval_context() {
1807 let source = indoc! { r#"
1808 namespace Test {
1809 function Hello() : String {
1810 "hello there..."
1811 }
1812 }
1813 namespace Test2 {
1814 open Test;
1815 operation Main() : String {
1816 Hello()
1817 }
1818 }"#};
1819
1820 let sources = SourceMap::new([("test".into(), source.into())], None);
1821 let store = crate::PackageStore::new(crate::compile::core());
1822 let mut interpreter = Interpreter::new(
1823 sources,
1824 PackageType::Lib,
1825 TargetCapabilityFlags::all(),
1826 LanguageFeatures::default(),
1827 store,
1828 &[],
1829 )
1830 .expect("interpreter should be created");
1831 let (result, output) = line(&mut interpreter, "Test.Hello()");
1832 is_only_value(&result, &output, &Value::String("hello there...".into()));
1833 let (result, output) = line(&mut interpreter, "Test2.Main()");
1834 is_only_value(&result, &output, &Value::String("hello there...".into()));
1835 }
1836
1837 #[test]
1838 fn runtime_error_from_stdlib() {
1839 let sources = SourceMap::new(
1840 [(
1841 "test".into(),
1842 "namespace Foo {
1843 operation Bar(): Unit {
1844 let x = -1;
1845 use qs = Qubit[x];
1846 }
1847 }
1848 "
1849 .into(),
1850 )],
1851 Some("Foo.Bar()".into()),
1852 );
1853
1854 let store = crate::PackageStore::new(crate::compile::core());
1855 let mut interpreter = Interpreter::new(
1856 sources,
1857 PackageType::Lib,
1858 TargetCapabilityFlags::all(),
1859 LanguageFeatures::default(),
1860 store,
1861 &[],
1862 )
1863 .expect("interpreter should be created");
1864
1865 let (result, output) = entry(&mut interpreter);
1866 is_only_error(
1867 &result,
1868 &output,
1869 &expect![[r#"
1870 runtime error: program failed: Cannot allocate qubit array with a negative length
1871 explicit fail [qsharp-library-source:core/qir.qs] [fail "Cannot allocate qubit array with a negative length"]
1872 "#]],
1873 );
1874 }
1875
1876 #[test]
1877 fn interpreter_returns_items_from_source() {
1878 let sources = SourceMap::new(
1879 [(
1880 "test".into(),
1881 "namespace A {
1882 operation B(): Unit { }
1883 }
1884 "
1885 .into(),
1886 )],
1887 Some("A.B()".into()),
1888 );
1889
1890 let (std_id, store) =
1891 crate::compile::package_store_with_stdlib(TargetCapabilityFlags::all());
1892 let interpreter = Interpreter::new(
1893 sources,
1894 PackageType::Lib,
1895 TargetCapabilityFlags::all(),
1896 LanguageFeatures::default(),
1897 store,
1898 &[(std_id, None)],
1899 )
1900 .expect("interpreter should be created");
1901
1902 let items = interpreter.user_globals();
1903 assert_eq!(1, items.len());
1904 expect![[r#"
1905 [
1906 "A",
1907 ]
1908 "#]]
1909 .assert_debug_eq(&items[0].0);
1910 expect![[r#"
1911 "B"
1912 "#]]
1913 .assert_debug_eq(&items[0].1);
1914 }
1915
1916 #[test]
1917 fn interpreter_can_be_created_from_ast() {
1918 let sources = SourceMap::new(
1919 [(
1920 "test".into(),
1921 "namespace A {
1922 operation B(): Result {
1923 use qs = Qubit[2];
1924 X(qs[0]);
1925 CNOT(qs[0], qs[1]);
1926 let res = Measure([PauliZ, PauliZ], qs[...1]);
1927 ResetAll(qs);
1928 res
1929 }
1930 }
1931 "
1932 .into(),
1933 )],
1934 Some("A.B()".into()),
1935 );
1936
1937 let (package_type, capabilities, language_features) = (
1938 PackageType::Lib,
1939 TargetCapabilityFlags::all(),
1940 LanguageFeatures::default(),
1941 );
1942
1943 let mut store = crate::PackageStore::new(crate::compile::core());
1944 let dependencies = vec![(
1945 store.insert(crate::compile::std(&store, capabilities)),
1946 None,
1947 )];
1948
1949 let (mut unit, errors) = crate::compile::compile(
1950 &store,
1951 &dependencies,
1952 sources,
1953 package_type,
1954 capabilities,
1955 language_features,
1956 );
1957 unit.expose();
1958 for e in &errors {
1959 eprintln!("{e:?}");
1960 }
1961 assert!(errors.is_empty(), "compilation failed: {}", errors[0]);
1962 let package_id = store.insert(unit);
1963
1964 let mut interpreter = Interpreter::from(
1965 store,
1966 package_id,
1967 capabilities,
1968 language_features,
1969 &dependencies,
1970 )
1971 .expect("interpreter should be created");
1972 let (result, output) = entry(&mut interpreter);
1973 is_only_value(
1974 &result,
1975 &output,
1976 &Value::Result(qsc_eval::val::Result::Val(false)),
1977 );
1978 }
1979
1980 #[test]
1981 fn ast_fragments_can_be_evaluated() {
1982 let sources = SourceMap::new(
1983 [(
1984 "test".into(),
1985 "namespace A {
1986 operation B(): Result {
1987 use qs = Qubit[2];
1988 X(qs[0]);
1989 CNOT(qs[0], qs[1]);
1990 let res = Measure([PauliZ, PauliZ], qs[...1]);
1991 ResetAll(qs);
1992 res
1993 }
1994 }
1995 "
1996 .into(),
1997 )],
1998 None,
1999 );
2000 let (std_id, store) =
2001 crate::compile::package_store_with_stdlib(TargetCapabilityFlags::all());
2002 let mut interpreter = Interpreter::new(
2003 sources,
2004 PackageType::Lib,
2005 TargetCapabilityFlags::all(),
2006 LanguageFeatures::default(),
2007 store,
2008 &[(std_id, None)],
2009 )
2010 .expect("interpreter should be created");
2011
2012 let package = get_package_for_call("A", "B");
2013 let (result, output) = fragment(&mut interpreter, "A.B()", package);
2014 is_only_value(
2015 &result,
2016 &output,
2017 &Value::Result(qsc_eval::val::Result::Val(false)),
2018 );
2019 }
2020
2021 #[test]
2022 fn ast_fragments_evaluation_returns_runtime_errors() {
2023 let sources = SourceMap::new(
2024 [(
2025 "test".into(),
2026 "namespace A {
2027 operation B(): Int {
2028 42 / 0
2029 }
2030 }
2031 "
2032 .into(),
2033 )],
2034 None,
2035 );
2036 let (std_id, store) =
2037 crate::compile::package_store_with_stdlib(TargetCapabilityFlags::all());
2038 let mut interpreter = Interpreter::new(
2039 sources,
2040 PackageType::Lib,
2041 TargetCapabilityFlags::all(),
2042 LanguageFeatures::default(),
2043 store,
2044 &[(std_id, None)],
2045 )
2046 .expect("interpreter should be created");
2047
2048 let package = get_package_for_call("A", "B");
2049 let (result, output) = fragment(&mut interpreter, "A.B()", package);
2050 is_only_error(
2051 &result,
2052 &output,
2053 &expect![[r#"
2054 runtime error: division by zero
2055 cannot divide by zero [test] [0]
2056 "#]],
2057 );
2058 }
2059
2060 fn get_package_for_call(ns: &str, name: &str) -> crate::ast::Package {
2061 let args = Expr {
2062 id: NodeId::default(),
2063 span: Span::default(),
2064 kind: Box::new(ExprKind::Tuple(Box::new([]))),
2065 };
2066 let path = Path {
2067 id: NodeId::default(),
2068 span: Span::default(),
2069 segments: Some(
2070 std::iter::once(qsc_ast::ast::Ident {
2071 id: NodeId::default(),
2072 span: Span::default(),
2073 name: ns.into(),
2074 })
2075 .collect(),
2076 ),
2077 name: Box::new(qsc_ast::ast::Ident {
2078 id: NodeId::default(),
2079 span: Span::default(),
2080 name: name.into(),
2081 }),
2082 };
2083 let path_expr = Expr {
2084 id: NodeId::default(),
2085 span: Span::default(),
2086 kind: Box::new(ExprKind::Path(PathKind::Ok(Box::new(path)))),
2087 };
2088 let expr = Expr {
2089 id: NodeId::default(),
2090 span: Span::default(),
2091 kind: Box::new(ExprKind::Call(Box::new(path_expr), Box::new(args))),
2092 };
2093 let stmt = Stmt {
2094 id: NodeId::default(),
2095 span: Span::default(),
2096 kind: Box::new(StmtKind::Expr(Box::new(expr))),
2097 };
2098 let top_level = TopLevelNode::Stmt(Box::new(stmt));
2099 Package {
2100 id: NodeId::default(),
2101 nodes: vec![top_level].into_boxed_slice(),
2102 entry: None,
2103 }
2104 }
2105 }
2106}
2107