microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
alex/testHarnessIntegTests

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc_frontend/src/resolve/tests.rs

5291lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use super::{Error, Locals, Names, Res};
5use crate::{
6 compile,
7 resolve::{LocalKind, Resolver},
8};
9use expect_test::{expect, Expect};
10use indoc::indoc;
11use qsc_ast::ast::{Idents, Item, ItemKind, PathKind};
12use qsc_ast::{
13 assigner::Assigner as AstAssigner,
14 ast::{Ident, NodeId, Package, Path, TopLevelNode},
15 mut_visit::MutVisitor,
16 visit::{self, Visitor},
17};
18
19use qsc_data_structures::{
20 language_features::LanguageFeatures,
21 namespaces::{NamespaceId, NamespaceTreeRoot},
22 span::Span,
23 target::TargetCapabilityFlags,
24};
25use qsc_hir::assigner::Assigner as HirAssigner;
26use rustc_hash::FxHashMap;
27use std::rc::Rc;
28use std::{fmt::Write, vec};
29
30#[derive(Debug)]
31enum Change {
32 Res(Res),
33 NamespaceId(NamespaceId),
34}
35
36impl From<Res> for Change {
37 fn from(res: Res) -> Self {
38 Self::Res(res)
39 }
40}
41
42impl From<NamespaceId> for Change {
43 fn from(ns_id: NamespaceId) -> Self {
44 Self::NamespaceId(ns_id)
45 }
46}
47
48struct Renamer<'a> {
49 names: &'a Names,
50 changes: Vec<(Span, Change)>,
51 namespaces: NamespaceTreeRoot,
52 aliases: FxHashMap<Vec<Rc<str>>, NamespaceId>,
53}
54
55impl<'a> Renamer<'a> {
56 fn new(names: &'a Names, namespaces: NamespaceTreeRoot) -> Self {
57 Self {
58 names,
59 changes: Vec::new(),
60 namespaces,
61 aliases: FxHashMap::default(),
62 }
63 }
64
65 fn rename(&self, input: &mut String) {
66 for (span, change) in self.changes.iter().rev() {
67 let name = match change {
68 Change::Res(res) => Self::format_res(res),
69 Change::NamespaceId(ns_id) => format!("namespace{}", Into::<usize>::into(ns_id)),
70 };
71 input.replace_range((span.lo as usize)..(span.hi as usize), &name);
72 }
73 }
74
75 fn format_res(res: &Res) -> String {
76 match res {
77 Res::Item(item, _) => match item.package {
78 None => format!("item{}", item.item),
79 Some(package) => format!("package{package}_item{}", item.item),
80 },
81 Res::Local(node) => format!("local{node}"),
82 Res::PrimTy(prim) => format!("{prim:?}"),
83 Res::UnitTy => "Unit".to_string(),
84 Res::Param { id, .. } => format!("param{id}"),
85 Res::ExportedItem(item, _) => match item.package {
86 None => format!("exported_item{}", item.item),
87 Some(package) => format!("reexport_from_{package}:{}", item.item),
88 },
89 }
90 }
91}
92
93impl Visitor<'_> for Renamer<'_> {
94 fn visit_path(&mut self, path: &Path) {
95 if let Some(res) = self.names.get(path.id) {
96 // The whole path node can be a resolved name
97 self.changes.push((path.span, res.clone().into()));
98 return;
99 }
100
101 let ns_id = self.find_namespace_id(path);
102 if let Some(ns_id) = ns_id {
103 // The whole path can be a namespace
104 self.changes.push((path.span, ns_id.into()));
105 return;
106 }
107
108 if let Some(segments) = &path.segments {
109 // The segments part can be a namespace
110 let ns_id = self.find_namespace_id(segments);
111 if let Some(ns_id) = ns_id {
112 self.changes.push((segments.full_span(), ns_id.into()));
113 return;
114 }
115 }
116
117 // Individual ident nodes can be resolved names
118 visit::walk_path(self, path);
119 }
120
121 fn visit_idents(&mut self, idents: &[Ident]) {
122 let ns_id = self.find_namespace_id(&idents);
123 if let Some(ns_id) = ns_id {
124 self.changes.push((idents.full_span(), ns_id.into()));
125 return;
126 }
127 visit::walk_idents(self, idents);
128 }
129
130 fn visit_ident(&mut self, ident: &Ident) {
131 if let Some(res) = self.names.get(ident.id) {
132 self.changes.push((ident.span, res.clone().into()));
133 }
134 }
135
136 fn visit_item(&mut self, item: &'_ Item) {
137 match &*item.kind {
138 ItemKind::Open(PathKind::Ok(namespace), Some(alias)) => {
139 if let Some(ns_id) = self.namespaces.get_namespace_id(namespace.str_iter()) {
140 // self.changes.push((item.span, ns_id.into()));
141 self.aliases.insert(vec![alias.name.clone()], ns_id);
142 } else {
143 return;
144 };
145 }
146 ItemKind::ImportOrExport(export) => {
147 for item in export.items() {
148 let PathKind::Ok(path) = &item.path else {
149 continue;
150 };
151 if let Some(res) = self.names.get(path.id) {
152 // Path node can be a resolved name
153 self.changes.push((item.span, (res.clone()).into()));
154 } else if let Some(namespace_id) =
155 self.namespaces.get_namespace_id(path.str_iter())
156 {
157 // Path can be a namespace
158 self.changes.push((
159 if item.alias.is_some() {
160 item.span
161 } else {
162 path.span
163 },
164 namespace_id.into(),
165 ));
166 }
167 }
168 return;
169 }
170 _ => (),
171 }
172 visit::walk_item(self, item);
173 }
174}
175
176impl<'a> Renamer<'a> {
177 fn find_namespace_id(&mut self, idents: &impl Idents) -> Option<NamespaceId> {
178 let ns_id = self
179 .namespaces
180 .get_namespace_id(idents.str_iter())
181 .or_else(|| {
182 self.aliases
183 .get(&idents.rc_str_iter().cloned().collect::<Vec<_>>())
184 .copied()
185 });
186 ns_id
187 }
188}
189
190fn check(input: &str, expect: &Expect) {
191 expect.assert_eq(&resolve_names(input, TargetCapabilityFlags::all()));
192}
193
194fn check_with_capabilities(input: &str, capabilities: TargetCapabilityFlags, expect: &Expect) {
195 expect.assert_eq(&resolve_names(input, capabilities));
196}
197
198fn resolve_names(input: &str, capabilities: TargetCapabilityFlags) -> String {
199 let (package, names, _, errors, namespaces) =
200 compile(input, LanguageFeatures::default(), capabilities);
201 let mut renamer = Renamer::new(&names, namespaces);
202 renamer.visit_package(&package);
203 let mut output = input.to_string();
204 renamer.rename(&mut output);
205 if !errors.is_empty() {
206 output += "\n";
207 }
208 for error in &errors {
209 writeln!(output, "// {error:?}").expect("string should be writable");
210 }
211 output
212}
213
214fn compile(
215 input: &str,
216 language_features: LanguageFeatures,
217 capabilities: TargetCapabilityFlags,
218) -> (Package, Names, Locals, Vec<Error>, NamespaceTreeRoot) {
219 let (namespaces, parse_errors) = qsc_parse::namespaces(input, None, language_features);
220 assert!(parse_errors.is_empty(), "parse failed: {parse_errors:#?}");
221 let mut package = Package {
222 id: NodeId::default(),
223 nodes: namespaces
224 .into_iter()
225 .map(TopLevelNode::Namespace)
226 .collect::<Vec<_>>()
227 .into_boxed_slice(),
228 entry: None,
229 };
230
231 AstAssigner::new().visit_package(&mut package);
232
233 let mut cond_compile = compile::preprocess::Conditional::new(capabilities);
234 cond_compile.visit_package(&mut package);
235 let dropped_names = cond_compile.into_names();
236
237 let mut assigner = HirAssigner::new();
238 // insert the core namespace
239
240 let mut globals = super::GlobalTable::new();
241 let mut errors = globals.add_local_package(&mut assigner, &package);
242 let mut resolver = Resolver::new(globals, dropped_names);
243 resolver.bind_and_resolve_imports_and_exports(&package);
244 resolver.with(&mut assigner).visit_package(&package);
245 let (names, locals, mut resolve_errors, namespaces) = resolver.into_result();
246 errors.append(&mut resolve_errors);
247 (package, names, locals, errors, namespaces)
248}
249
250#[test]
251fn global_callable() {
252 check(
253 indoc! {"
254 namespace Foo {
255 function A() : Unit {}
256
257 function B() : Unit {
258 A();
259 }
260 }
261 "},
262 &expect![[r#"
263 namespace namespace3 {
264 function item1() : Unit {}
265
266 function item2() : Unit {
267 item1();
268 }
269 }
270 "#]],
271 );
272}
273
274#[test]
275fn global_callable_recursive() {
276 check(
277 indoc! {
278 "namespace Foo {
279 function A() : Unit {
280 A();
281 }
282 }
283 "},
284 &expect![[r#"
285 namespace namespace3 {
286 function item1() : Unit {
287 item1();
288 }
289 }
290 "#]],
291 );
292}
293
294#[test]
295fn global_callable_internal() {
296 check(
297 indoc! {"
298 namespace Foo {
299 internal function A() : Unit {}
300
301 function B() : Unit {
302 A();
303 }
304 }
305 "},
306 &expect![[r#"
307 namespace namespace3 {
308 internal function item1() : Unit {}
309
310 function item2() : Unit {
311 item1();
312 }
313 }
314 "#]],
315 );
316}
317
318#[test]
319fn global_callable_duplicate_error() {
320 check(
321 indoc! {"
322 namespace Foo {
323 function A() : Unit {}
324 operation A() : Unit {}
325 }
326 "},
327 &expect![[r#"
328 namespace namespace3 {
329 function item1() : Unit {}
330 operation item2() : Unit {}
331 }
332
333 // Duplicate("A", "Foo", Span { lo: 57, hi: 58 })
334 "#]],
335 );
336}
337
338#[test]
339fn global_path() {
340 check(
341 indoc! {"
342 namespace Foo {
343 function A() : Unit {}
344 }
345
346 namespace Bar {
347 function B() : Unit {
348 Foo.A();
349 }
350 }
351 "},
352 &expect![[r#"
353 namespace namespace3 {
354 function item1() : Unit {}
355 }
356
357 namespace namespace4 {
358 function item3() : Unit {
359 item1();
360 }
361 }
362 "#]],
363 );
364}
365
366#[test]
367fn open_namespace() {
368 check(
369 indoc! {"
370 namespace Foo {
371 function A() : Unit {}
372 }
373
374 namespace Bar {
375 open Foo;
376
377 function B() : Unit {
378 A();
379 }
380 }
381 "},
382 &expect![[r#"
383 namespace namespace3 {
384 function item1() : Unit {}
385 }
386
387 namespace namespace4 {
388 open namespace3;
389
390 function item3() : Unit {
391 item1();
392 }
393 }
394 "#]],
395 );
396}
397
398#[test]
399fn open_alias() {
400 check(
401 indoc! {"
402 namespace Foo {
403 function A() : Unit {}
404 }
405
406 namespace Bar {
407 open Foo as F;
408
409 function B() : Unit {
410 F.A();
411 }
412 }
413 "},
414 &expect![[r#"
415 namespace namespace3 {
416 function item1() : Unit {}
417 }
418
419 namespace namespace4 {
420 open namespace3 as F;
421
422 function item3() : Unit {
423 item1();
424 }
425 }
426 "#]],
427 );
428}
429
430#[test]
431fn prelude_callable() {
432 check(
433 indoc! {"
434 namespace Std.Core {
435 function A() : Unit {}
436 }
437
438 namespace Foo {
439 function B() : Unit {
440 A();
441 }
442 }
443 "},
444 &expect![[r#"
445 namespace namespace2 {
446 function item1() : Unit {}
447 }
448
449 namespace namespace3 {
450 function item3() : Unit {
451 item1();
452 }
453 }
454 "#]],
455 );
456}
457
458#[test]
459fn parent_namespace_shadows_prelude() {
460 check(
461 indoc! {"
462 namespace Std.Core {
463 function A() : Unit {}
464 }
465
466 namespace Foo {
467 function A() : Unit {}
468
469 function B() : Unit {
470 A();
471 }
472 }
473 "},
474 &expect![[r#"
475 namespace namespace2 {
476 function item1() : Unit {}
477 }
478
479 namespace namespace3 {
480 function item3() : Unit {}
481
482 function item4() : Unit {
483 item3();
484 }
485 }
486 "#]],
487 );
488}
489
490#[test]
491fn open_shadows_prelude() {
492 check(
493 indoc! {"
494 namespace Std.Core {
495 function A() : Unit {}
496 }
497
498 namespace Foo {
499 function A() : Unit {}
500 }
501
502 namespace Bar {
503 open Foo;
504
505 function B() : Unit {
506 A();
507 }
508 }
509 "},
510 &expect![[r#"
511 namespace namespace2 {
512 function item1() : Unit {}
513 }
514
515 namespace namespace3 {
516 function item3() : Unit {}
517 }
518
519 namespace namespace4 {
520 open namespace3;
521
522 function item5() : Unit {
523 item3();
524 }
525 }
526 "#]],
527 );
528}
529
530#[test]
531fn ambiguous_prelude() {
532 check(
533 indoc! {"
534 namespace Std.Canon {
535 function A() : Unit {}
536 }
537
538 namespace Std.Measurement {
539 function A() : Unit {}
540 }
541
542 namespace Foo {
543 function B() : Unit {
544 A();
545 }
546 }
547 "},
548 &expect![[r#"
549 namespace namespace3 {
550 function item1() : Unit {}
551 }
552
553 namespace namespace4 {
554 function item3() : Unit {}
555 }
556
557 namespace namespace5 {
558 function item5() : Unit {
559 A();
560 }
561 }
562
563 // AmbiguousPrelude { name: "A", candidate_a: "Std.Canon", candidate_b: "Std.Measurement", span: Span { lo: 160, hi: 161 } }
564 "#]],
565 );
566}
567
568#[test]
569fn local_var() {
570 check(
571 indoc! {"
572 namespace Foo {
573 function A() : Int {
574 let x = 0;
575 x
576 }
577 }
578 "},
579 &expect![[r#"
580 namespace namespace3 {
581 function item1() : Int {
582 let local13 = 0;
583 local13
584 }
585 }
586 "#]],
587 );
588}
589
590#[test]
591fn shadow_local() {
592 check(
593 indoc! {"
594 namespace Foo {
595 function A() : Int {
596 let x = 0;
597 let y = {
598 let x = 1;
599 x
600 };
601 x + y
602 }
603 }
604 "},
605 &expect![[r#"
606 namespace namespace3 {
607 function item1() : Int {
608 let local13 = 0;
609 let local17 = {
610 let local22 = 1;
611 local22
612 };
613 local13 + local17
614 }
615 }
616 "#]],
617 );
618}
619
620#[test]
621fn callable_param() {
622 check(
623 indoc! {"
624 namespace Foo {
625 function A(x : Int) : Int {
626 x
627 }
628 }
629 "},
630 &expect![[r#"
631 namespace namespace3 {
632 function item1(local8 : Int) : Int {
633 local8
634 }
635 }
636 "#]],
637 );
638}
639
640#[test]
641fn spec_param() {
642 check(
643 indoc! {"
644 namespace Foo {
645 operation A(q : Qubit) : (Qubit[], Qubit) {
646 controlled (cs, ...) {
647 (cs, q)
648 }
649 }
650 }
651 "},
652 &expect![[r#"
653 namespace namespace3 {
654 operation item1(local8 : Qubit) : (Qubit[], Qubit) {
655 controlled (local23, ...) {
656 (local23, local8)
657 }
658 }
659 }
660 "#]],
661 );
662}
663
664#[test]
665fn spec_param_shadow_disallowed() {
666 check(
667 indoc! {"
668 namespace Foo {
669 operation A(qs : Qubit[]) : Qubit[] {
670 controlled (qs, ...) {
671 qs
672 }
673 body ... {
674 qs
675 }
676 }
677 }
678 "},
679 &expect![[r#"
680 namespace namespace3 {
681 operation item1(local8 : Qubit[]) : Qubit[] {
682 controlled (local20, ...) {
683 local20
684 }
685 body ... {
686 local8
687 }
688 }
689 }
690
691 // DuplicateBinding("qs", Span { lo: 78, hi: 80 })
692 "#]],
693 );
694}
695
696#[test]
697fn local_shadows_global() {
698 check(
699 indoc! {"
700 namespace Foo {
701 function x() : Unit {}
702
703 function y() : Int {
704 x();
705 let x = 1;
706 x
707 }
708 }
709 "},
710 &expect![[r#"
711 namespace namespace3 {
712 function item1() : Unit {}
713
714 function item2() : Int {
715 item1();
716 let local27 = 1;
717 local27
718 }
719 }
720 "#]],
721 );
722}
723
724#[test]
725fn shadow_same_block() {
726 check(
727 indoc! {"
728 namespace Foo {
729 function A() : Int {
730 let x = 0;
731 let x = x + 1;
732 x
733 }
734 }
735 "},
736 &expect![[r#"
737 namespace namespace3 {
738 function item1() : Int {
739 let local13 = 0;
740 let local17 = local13 + 1;
741 local17
742 }
743 }
744 "#]],
745 );
746}
747
748#[test]
749fn parent_namespace_shadows_open() {
750 check(
751 indoc! {"
752 namespace Foo {
753 function A() : Unit {}
754 }
755
756 namespace Bar {
757 open Foo;
758
759 function A() : Unit {}
760
761 function B() : Unit {
762 A();
763 }
764 }
765 "},
766 &expect![[r#"
767 namespace namespace3 {
768 function item1() : Unit {}
769 }
770
771 namespace namespace4 {
772 open namespace3;
773
774 function item3() : Unit {}
775
776 function item4() : Unit {
777 item3();
778 }
779 }
780 "#]],
781 );
782}
783
784#[test]
785fn open_alias_shadows_global() {
786 check(
787 indoc! {"
788 namespace Foo {
789 function A() : Unit {}
790 }
791
792 namespace Bar {
793 function A() : Unit {}
794 }
795
796 namespace Baz {
797 open Foo as Bar;
798
799 function B() : Unit {
800 Bar.A();
801 }
802 }
803 "},
804 &expect![[r#"
805 namespace namespace3 {
806 function item1() : Unit {}
807 }
808
809 namespace namespace4 {
810 function item3() : Unit {}
811 }
812
813 namespace namespace5 {
814 open namespace3 as Bar;
815
816 function item5() : Unit {
817 item1();
818 }
819 }
820 "#]],
821 );
822}
823
824#[test]
825fn shadowing_disallowed_within_parameters() {
826 check(
827 indoc! {"
828 namespace Test {
829 operation Foo(x: Int, y: Double, x: Bool) : Unit {}
830 }
831 "},
832 &expect![[r#"
833 namespace namespace3 {
834 operation item1(local8: Int, local13: Double, local18: Bool) : Unit {}
835 }
836
837 // DuplicateBinding("x", Span { lo: 54, hi: 55 })
838 "#]],
839 );
840}
841
842#[test]
843fn shadowing_disallowed_within_local_binding() {
844 check(
845 indoc! {"
846 namespace Test {
847 operation Foo() : Unit {
848 let (first, second, first) = (1, 2, 3);
849 }
850 }
851 "},
852 &expect![[r#"
853 namespace namespace3 {
854 operation item1() : Unit {
855 let (local14, local16, local18) = (1, 2, 3);
856 }
857 }
858
859 // DuplicateBinding("first", Span { lo: 74, hi: 79 })
860 "#]],
861 );
862}
863
864#[test]
865fn shadowing_disallowed_within_for_loop() {
866 check(
867 indoc! {"
868 namespace Test {
869 operation Foo() : Unit {
870 for (key, val, key) in [(1, 1, 1)] {}
871 }
872 }
873 "},
874 &expect![[r#"
875 namespace namespace3 {
876 operation item1() : Unit {
877 for (local15, local17, local19) in [(1, 1, 1)] {}
878 }
879 }
880
881 // DuplicateBinding("key", Span { lo: 69, hi: 72 })
882 "#]],
883 );
884}
885
886#[test]
887fn shadowing_disallowed_within_lambda_param() {
888 check(
889 indoc! {"
890 namespace Test {
891 operation Foo() : Unit {
892 let f = (x, y, x) -> x + y + 1;
893 }
894 }
895 "},
896 &expect![[r#"
897 namespace namespace3 {
898 operation item1() : Unit {
899 let local13 = (local17, local19, local21) -> local21 + local19 + 1;
900 }
901 }
902
903 // DuplicateBinding("x", Span { lo: 69, hi: 70 })
904 "#]],
905 );
906}
907
908#[test]
909fn merged_aliases() {
910 check(
911 indoc! {"
912 namespace Foo {
913 function A() : Unit {}
914 }
915
916 namespace Bar {
917 function B() : Unit {}
918 }
919
920 namespace Baz {
921 open Foo as Alias;
922 open Bar as Alias;
923
924 function C() : Unit {
925 Alias.A();
926 Alias.B();
927 }
928 }
929 "},
930 &expect![[r#"
931 namespace namespace3 {
932 function item1() : Unit {}
933 }
934
935 namespace namespace4 {
936 function item3() : Unit {}
937 }
938
939 namespace namespace5 {
940 open namespace3 as Alias;
941 open namespace4 as Alias;
942
943 function item5() : Unit {
944 item1();
945 item3();
946 }
947 }
948 "#]],
949 );
950}
951
952#[test]
953fn ty_decl() {
954 check(
955 indoc! {"
956 namespace Foo {
957 newtype A = Unit;
958 function B(a : A) : Unit {}
959 }
960 "},
961 &expect![[r#"
962 namespace namespace3 {
963 newtype item1 = Unit;
964 function item2(local14 : item1) : Unit {}
965 }
966 "#]],
967 );
968}
969
970#[test]
971fn struct_decl() {
972 check(
973 indoc! {"
974 namespace Foo {
975 struct A {}
976 function B(a : A) : Unit {}
977 }
978 "},
979 &expect![[r#"
980 namespace namespace3 {
981 struct item1 {}
982 function item2(local11 : item1) : Unit {}
983 }
984 "#]],
985 );
986}
987
988#[test]
989fn ty_decl_duplicate_error() {
990 check(
991 indoc! {"
992 namespace Foo {
993 newtype A = Unit;
994 newtype A = Bool;
995 }
996 "},
997 &expect![[r#"
998 namespace namespace3 {
999 newtype item1 = Unit;
1000 newtype item2 = Bool;
1001 }
1002
1003 // Duplicate("A", "Foo", Span { lo: 50, hi: 51 })
1004 "#]],
1005 );
1006}
1007
1008#[test]
1009fn struct_decl_duplicate_error() {
1010 check(
1011 indoc! {"
1012 namespace Foo {
1013 struct A {}
1014 struct A { first : Bool }
1015 }
1016 "},
1017 &expect![[r#"
1018 namespace namespace3 {
1019 struct item1 {}
1020 struct item2 { first : Bool }
1021 }
1022
1023 // Duplicate("A", "Foo", Span { lo: 43, hi: 44 })
1024 "#]],
1025 );
1026}
1027
1028#[test]
1029fn ty_decl_duplicate_error_on_built_in_ty() {
1030 check(
1031 indoc! {"
1032 namespace Std.Core {
1033 newtype Pauli = Unit;
1034 }
1035 "},
1036 &expect![[r#"
1037 namespace namespace2 {
1038 newtype item1 = Unit;
1039 }
1040
1041 // Duplicate("Pauli", "Std.Core", Span { lo: 33, hi: 38 })
1042 "#]],
1043 );
1044}
1045
1046#[test]
1047fn struct_decl_duplicate_error_on_built_in_ty() {
1048 check(
1049 indoc! {"
1050 namespace Std.Core {
1051 struct Pauli {}
1052 }
1053 "},
1054 &expect![[r#"
1055 namespace namespace2 {
1056 struct item1 {}
1057 }
1058
1059 // Duplicate("Pauli", "Std.Core", Span { lo: 32, hi: 37 })
1060 "#]],
1061 );
1062}
1063
1064#[test]
1065fn ty_decl_in_ty_decl() {
1066 check(
1067 indoc! {"
1068 namespace Foo {
1069 newtype A = Unit;
1070 newtype B = A;
1071 }
1072 "},
1073 &expect![[r#"
1074 namespace namespace3 {
1075 newtype item1 = Unit;
1076 newtype item2 = item1;
1077 }
1078 "#]],
1079 );
1080}
1081
1082#[test]
1083fn struct_decl_in_struct_decl() {
1084 check(
1085 indoc! {"
1086 namespace Foo {
1087 struct A {}
1088 struct B { a : A }
1089 }
1090 "},
1091 &expect![[r#"
1092 namespace namespace3 {
1093 struct item1 {}
1094 struct item2 { a : item1 }
1095 }
1096 "#]],
1097 );
1098}
1099
1100#[test]
1101fn ty_decl_recursive() {
1102 check(
1103 indoc! {"
1104 namespace Foo {
1105 newtype A = A;
1106 }
1107 "},
1108 &expect![[r#"
1109 namespace namespace3 {
1110 newtype item1 = item1;
1111 }
1112 "#]],
1113 );
1114}
1115
1116#[test]
1117fn struct_decl_recursive() {
1118 check(
1119 indoc! {"
1120 namespace Foo {
1121 struct A { a : A }
1122 }
1123 "},
1124 &expect![[r#"
1125 namespace namespace3 {
1126 struct item1 { a : item1 }
1127 }
1128 "#]],
1129 );
1130}
1131
1132#[test]
1133fn ty_decl_cons() {
1134 check(
1135 indoc! {"
1136 namespace Foo {
1137 newtype A = Unit;
1138
1139 function B() : A {
1140 A()
1141 }
1142 }
1143 "},
1144 &expect![[r#"
1145 namespace namespace3 {
1146 newtype item1 = Unit;
1147
1148 function item2() : item1 {
1149 item1()
1150 }
1151 }
1152 "#]],
1153 );
1154}
1155
1156#[test]
1157fn struct_decl_call_cons() {
1158 check(
1159 indoc! {"
1160 namespace Foo {
1161 struct A {}
1162
1163 function B() : A {
1164 A()
1165 }
1166 }
1167 "},
1168 &expect![[r#"
1169 namespace namespace3 {
1170 struct item1 {}
1171
1172 function item2() : item1 {
1173 item1()
1174 }
1175 }
1176 "#]],
1177 );
1178}
1179
1180#[test]
1181fn struct_decl_cons() {
1182 check(
1183 indoc! {"
1184 namespace Foo {
1185 struct A {}
1186
1187 function B() : A {
1188 new A {}
1189 }
1190 }
1191 "},
1192 &expect![[r#"
1193 namespace namespace3 {
1194 struct item1 {}
1195
1196 function item2() : item1 {
1197 new item1 {}
1198 }
1199 }
1200 "#]],
1201 );
1202}
1203
1204#[test]
1205fn struct_decl_cons_with_fields() {
1206 check(
1207 indoc! {"
1208 namespace Foo {
1209 struct A {}
1210 struct B {}
1211 struct C { a : A, b : B }
1212
1213 function D() : C {
1214 new C { a = new A {}, b = new B {} }
1215 }
1216 }
1217 "},
1218 &expect![[r#"
1219 namespace namespace3 {
1220 struct item1 {}
1221 struct item2 {}
1222 struct item3 { a : item1, b : item2 }
1223
1224 function item4() : item3 {
1225 new item3 { a = new item1 {}, b = new item2 {} }
1226 }
1227 }
1228 "#]],
1229 );
1230}
1231
1232#[test]
1233fn struct_field_accessor() {
1234 check(
1235 indoc! {"
1236 namespace Foo {
1237 struct A { b : B }
1238 struct B { c : C}
1239 struct C { i : Int }
1240
1241 function D() : Unit {
1242 let a = new A { b = new B { c = new C { i = 4 } } };
1243 let i = a.b.c.i;
1244 }
1245 }
1246 "},
1247 &expect![[r#"
1248 namespace namespace3 {
1249 struct item1 { b : item2 }
1250 struct item2 { c : item3}
1251 struct item3 { i : Int }
1252
1253 function item4() : Unit {
1254 let local37 = new item1 { b = new item2 { c = new item3 { i = 4 } } };
1255 let local56 = local37.b.c.i;
1256 }
1257 }
1258 "#]],
1259 );
1260}
1261
1262#[test]
1263fn struct_field_accessor_with_expr() {
1264 check(
1265 indoc! {"
1266 namespace Foo {
1267 struct A { b : B }
1268 struct B { c : C}
1269 struct C { i : Int }
1270
1271 function D() : Unit {
1272 let a = new A { b = new B { c = new C { i = 4 } } };
1273 let i = { a }.b.c.i;
1274 }
1275 }
1276 "},
1277 &expect![[r#"
1278 namespace namespace3 {
1279 struct item1 { b : item2 }
1280 struct item2 { c : item3}
1281 struct item3 { i : Int }
1282
1283 function item4() : Unit {
1284 let local37 = new item1 { b = new item2 { c = new item3 { i = 4 } } };
1285 let local56 = { local37 }.b.c.i;
1286 }
1287 }
1288 "#]],
1289 );
1290}
1291
1292#[test]
1293fn unknown_term() {
1294 check(
1295 indoc! {"
1296 namespace Foo {
1297 function A() : Unit {
1298 B();
1299 }
1300 }
1301 "},
1302 &expect![[r#"
1303 namespace namespace3 {
1304 function item1() : Unit {
1305 B();
1306 }
1307 }
1308
1309 // NotFound("B", Span { lo: 50, hi: 51 })
1310 "#]],
1311 );
1312}
1313
1314#[test]
1315fn unknown_ty() {
1316 check(
1317 indoc! {"
1318 namespace Foo {
1319 function A(b : B) : Unit {}
1320 }
1321 "},
1322 &expect![[r#"
1323 namespace namespace3 {
1324 function item1(local8 : B) : Unit {}
1325 }
1326
1327 // NotFound("B", Span { lo: 35, hi: 36 })
1328 "#]],
1329 );
1330}
1331
1332#[test]
1333fn open_ambiguous_terms() {
1334 check(
1335 indoc! {"
1336 namespace Foo {
1337 function A() : Unit {}
1338 }
1339
1340 namespace Bar {
1341 function A() : Unit {}
1342 }
1343
1344 namespace Baz {
1345 open Foo;
1346 open Bar;
1347
1348 function C() : Unit {
1349 A();
1350 }
1351 }
1352 "},
1353 &expect![[r#"
1354 namespace namespace3 {
1355 function item1() : Unit {}
1356 }
1357
1358 namespace namespace4 {
1359 function item3() : Unit {}
1360 }
1361
1362 namespace namespace5 {
1363 open namespace3;
1364 open namespace4;
1365
1366 function item5() : Unit {
1367 A();
1368 }
1369 }
1370
1371 // Ambiguous { name: "A", first_open: "Foo", second_open: "Bar", name_span: Span { lo: 171, hi: 172 }, first_open_span: Span { lo: 117, hi: 120 }, second_open_span: Span { lo: 131, hi: 134 } }
1372 "#]],
1373 );
1374}
1375
1376#[test]
1377fn open_ambiguous_tys() {
1378 check(
1379 indoc! {"
1380 namespace Foo {
1381 newtype A = Unit;
1382 }
1383
1384 namespace Bar {
1385 newtype A = Unit;
1386 }
1387
1388 namespace Baz {
1389 open Foo;
1390 open Bar;
1391
1392 function C(a : A) : Unit {}
1393 }
1394 "},
1395 &expect![[r#"
1396 namespace namespace3 {
1397 newtype item1 = Unit;
1398 }
1399
1400 namespace namespace4 {
1401 newtype item3 = Unit;
1402 }
1403
1404 namespace namespace5 {
1405 open namespace3;
1406 open namespace4;
1407
1408 function item5(local30 : A) : Unit {}
1409 }
1410
1411 // Ambiguous { name: "A", first_open: "Foo", second_open: "Bar", name_span: Span { lo: 146, hi: 147 }, first_open_span: Span { lo: 107, hi: 110 }, second_open_span: Span { lo: 121, hi: 124 } }
1412 "#]],
1413 );
1414}
1415
1416#[test]
1417fn merged_aliases_ambiguous_terms() {
1418 check(
1419 indoc! {"
1420 namespace Foo {
1421 function A() : Unit {}
1422 }
1423
1424 namespace Bar {
1425 function A() : Unit {}
1426 }
1427
1428 namespace Baz {
1429 open Foo as Alias;
1430 open Bar as Alias;
1431
1432 function C() : Unit {
1433 Alias.A();
1434 }
1435 }
1436 "},
1437 &expect![[r#"
1438 namespace namespace3 {
1439 function item1() : Unit {}
1440 }
1441
1442 namespace namespace4 {
1443 function item3() : Unit {}
1444 }
1445
1446 namespace namespace5 {
1447 open namespace3 as Alias;
1448 open namespace4 as Alias;
1449
1450 function item5() : Unit {
1451 namespace4.A();
1452 }
1453 }
1454
1455 // Ambiguous { name: "A", first_open: "Foo", second_open: "Bar", name_span: Span { lo: 195, hi: 196 }, first_open_span: Span { lo: 117, hi: 120 }, second_open_span: Span { lo: 140, hi: 143 } }
1456 "#]],
1457 );
1458}
1459
1460#[test]
1461fn merged_aliases_ambiguous_tys() {
1462 check(
1463 indoc! {"
1464 namespace Foo {
1465 newtype A = Unit;
1466 }
1467
1468 namespace Bar {
1469 newtype A = Unit;
1470 }
1471
1472 namespace Baz {
1473 open Foo as Alias;
1474 open Bar as Alias;
1475
1476 function C(a : Alias.A) : Unit {}
1477 }
1478 "},
1479 &expect![[r#"
1480 namespace namespace3 {
1481 newtype item1 = Unit;
1482 }
1483
1484 namespace namespace4 {
1485 newtype item3 = Unit;
1486 }
1487
1488 namespace namespace5 {
1489 open namespace3 as Alias;
1490 open namespace4 as Alias;
1491
1492 function item5(local32 : namespace4.A) : Unit {}
1493 }
1494
1495 // Ambiguous { name: "A", first_open: "Foo", second_open: "Bar", name_span: Span { lo: 170, hi: 171 }, first_open_span: Span { lo: 107, hi: 110 }, second_open_span: Span { lo: 130, hi: 133 } }
1496 "#]],
1497 );
1498}
1499
1500#[test]
1501fn lambda_param() {
1502 check(
1503 indoc! {"
1504 namespace Foo {
1505 function A() : Unit {
1506 let f = x -> x + 1;
1507 }
1508 }
1509 "},
1510 &expect![[r#"
1511 namespace namespace3 {
1512 function item1() : Unit {
1513 let local13 = local16 -> local16 + 1;
1514 }
1515 }
1516 "#]],
1517 );
1518}
1519
1520#[test]
1521fn lambda_shadows_local() {
1522 check(
1523 indoc! {"
1524 namespace Foo {
1525 function A() : Int {
1526 let x = 1;
1527 let f = x -> x + 1;
1528 x
1529 }
1530 }
1531 "},
1532 &expect![[r#"
1533 namespace namespace3 {
1534 function item1() : Int {
1535 let local13 = 1;
1536 let local17 = local20 -> local20 + 1;
1537 local13
1538 }
1539 }
1540 "#]],
1541 );
1542}
1543
1544#[test]
1545fn for_loop_range() {
1546 check(
1547 indoc! {"
1548 namespace Foo {
1549 function A() : Unit {
1550 for i in 0..9 {
1551 let _ = i;
1552 }
1553 }
1554 }
1555 "},
1556 &expect![[r#"
1557 namespace namespace3 {
1558 function item1() : Unit {
1559 for local14 in 0..9 {
1560 let _ = local14;
1561 }
1562 }
1563 }
1564 "#]],
1565 );
1566}
1567
1568#[test]
1569fn for_loop_var() {
1570 check(
1571 indoc! {"
1572 namespace Foo {
1573 function A(xs : Int[]) : Unit {
1574 for x in xs {
1575 let _ = x;
1576 }
1577 }
1578 }
1579 "},
1580 &expect![[r#"
1581 namespace namespace3 {
1582 function item1(local8 : Int[]) : Unit {
1583 for local20 in local8 {
1584 let _ = local20;
1585 }
1586 }
1587 }
1588 "#]],
1589 );
1590}
1591
1592#[test]
1593fn repeat_until() {
1594 check(
1595 indoc! {"
1596 namespace Foo {
1597 operation A() : Unit {
1598 mutable cond = false;
1599 repeat {
1600 set cond = true;
1601 } until cond;
1602 }
1603 }
1604 "},
1605 &expect![[r#"
1606 namespace namespace3 {
1607 operation item1() : Unit {
1608 mutable local13 = false;
1609 repeat {
1610 set local13 = true;
1611 } until local13;
1612 }
1613 }
1614 "#]],
1615 );
1616}
1617
1618#[test]
1619fn repeat_until_fixup() {
1620 check(
1621 indoc! {"
1622 namespace Foo {
1623 operation A() : Unit {
1624 mutable cond = false;
1625 repeat {
1626 set cond = false;
1627 } until cond
1628 fixup {
1629 set cond = true;
1630 }
1631 }
1632 }
1633 "},
1634 &expect![[r#"
1635 namespace namespace3 {
1636 operation item1() : Unit {
1637 mutable local13 = false;
1638 repeat {
1639 set local13 = false;
1640 } until local13
1641 fixup {
1642 set local13 = true;
1643 }
1644 }
1645 }
1646 "#]],
1647 );
1648}
1649
1650#[test]
1651fn repeat_until_fixup_scoping() {
1652 check(
1653 indoc! {"
1654 namespace Foo {
1655 operation A() : Unit {
1656 repeat {
1657 mutable cond = false;
1658 }
1659 until cond
1660 fixup {
1661 set cond = true;
1662 }
1663 }
1664 }"},
1665 &expect![[r#"
1666 namespace namespace3 {
1667 operation item1() : Unit {
1668 repeat {
1669 mutable local16 = false;
1670 }
1671 until cond
1672 fixup {
1673 set cond = true;
1674 }
1675 }
1676 }
1677 // NotFound("cond", Span { lo: 118, hi: 122 })
1678 // NotFound("cond", Span { lo: 155, hi: 159 })
1679 "#]],
1680 );
1681}
1682
1683#[test]
1684fn use_qubit() {
1685 check(
1686 indoc! {"
1687 namespace Foo {
1688 operation X(q : Qubit) : Unit {
1689 body intrinsic;
1690 }
1691 operation A() : Unit {
1692 use q = Qubit();
1693 X(q);
1694 }
1695 }
1696 "},
1697 &expect![[r#"
1698 namespace namespace3 {
1699 operation item1(local8 : Qubit) : Unit {
1700 body intrinsic;
1701 }
1702 operation item2() : Unit {
1703 use local26 = Qubit();
1704 item1(local26);
1705 }
1706 }
1707 "#]],
1708 );
1709}
1710
1711#[test]
1712fn use_qubit_block() {
1713 check(
1714 indoc! {"
1715 namespace Foo {
1716 operation X(q : Qubit) : Unit {
1717 body intrinsic;
1718 }
1719 operation A() : Unit {
1720 use q = Qubit() {
1721 X(q);
1722 }
1723 }
1724 }
1725 "},
1726 &expect![[r#"
1727 namespace namespace3 {
1728 operation item1(local8 : Qubit) : Unit {
1729 body intrinsic;
1730 }
1731 operation item2() : Unit {
1732 use local26 = Qubit() {
1733 item1(local26);
1734 }
1735 }
1736 }
1737 "#]],
1738 );
1739}
1740
1741#[test]
1742fn use_qubit_block_qubit_restricted_to_block_scope() {
1743 check(
1744 indoc! {"
1745 namespace Foo {
1746 operation X(q : Qubit) : Unit {
1747 body intrinsic;
1748 }
1749 operation A() : Unit {
1750 use q = Qubit() {
1751 X(q);
1752 }
1753 X(q);
1754 }
1755 }
1756 "},
1757 &expect![[r#"
1758 namespace namespace3 {
1759 operation item1(local8 : Qubit) : Unit {
1760 body intrinsic;
1761 }
1762 operation item2() : Unit {
1763 use local26 = Qubit() {
1764 item1(local26);
1765 }
1766 item1(q);
1767 }
1768 }
1769
1770 // NotFound("q", Span { lo: 173, hi: 174 })
1771 "#]],
1772 );
1773}
1774
1775#[test]
1776fn local_function() {
1777 check(
1778 indoc! {"
1779 namespace A {
1780 function Foo() : Int {
1781 function Bar() : Int { 2 }
1782 Bar() + 1
1783 }
1784 }
1785 "},
1786 &expect![[r#"
1787 namespace namespace3 {
1788 function item1() : Int {
1789 function item2() : Int { 2 }
1790 item2() + 1
1791 }
1792 }
1793 "#]],
1794 );
1795}
1796
1797#[test]
1798fn local_function_use_before_declare() {
1799 check(
1800 indoc! {"
1801 namespace A {
1802 function Foo() : () {
1803 Bar();
1804 function Bar() : () {}
1805 }
1806 }
1807 "},
1808 &expect![[r#"
1809 namespace namespace3 {
1810 function item1() : () {
1811 item2();
1812 function item2() : () {}
1813 }
1814 }
1815 "#]],
1816 );
1817}
1818
1819#[test]
1820fn local_function_is_really_local() {
1821 check(
1822 indoc! {"
1823 namespace A {
1824 function Foo() : () {
1825 function Bar() : () {}
1826 Bar();
1827 }
1828
1829 function Baz() : () { Bar(); }
1830 }
1831 "},
1832 &expect![[r#"
1833 namespace namespace3 {
1834 function item1() : () {
1835 function item3() : () {}
1836 item3();
1837 }
1838
1839 function item2() : () { Bar(); }
1840 }
1841
1842 // NotFound("Bar", Span { lo: 119, hi: 122 })
1843 "#]],
1844 );
1845}
1846
1847#[test]
1848fn local_function_is_not_closure() {
1849 check(
1850 indoc! {"
1851 namespace A {
1852 function Foo() : () {
1853 let x = 2;
1854 function Bar() : Int { x }
1855 }
1856 }
1857 "},
1858 &expect![[r#"
1859 namespace namespace3 {
1860 function item1() : () {
1861 let local11 = 2;
1862 function item2() : Int { x }
1863 }
1864 }
1865
1866 // NotFound("x", Span { lo: 90, hi: 91 })
1867 "#]],
1868 );
1869}
1870
1871#[test]
1872fn local_type() {
1873 check(
1874 indoc! {"
1875 namespace A {
1876 function Foo() : () {
1877 newtype Bar = Int;
1878 let x = Bar(5);
1879 }
1880 }
1881 "},
1882 &expect![[r#"
1883 namespace namespace3 {
1884 function item1() : () {
1885 newtype item2 = Int;
1886 let local18 = item2(5);
1887 }
1888 }
1889 "#]],
1890 );
1891}
1892
1893#[test]
1894fn local_open() {
1895 check(
1896 indoc! {"
1897 namespace A { function Foo() : () { open B; Bar(); } }
1898 namespace B { function Bar() : () {} }
1899 "},
1900 &expect![[r#"
1901 namespace namespace3 { function item1() : () { open namespace4; item3(); } }
1902 namespace namespace4 { function item3() : () {} }
1903 "#]],
1904 );
1905}
1906
1907#[test]
1908fn local_open_shadows_parent_item() {
1909 check(
1910 indoc! {"
1911 namespace A {
1912 function Bar() : () {}
1913 function Foo() : () { open B; Bar(); }
1914 }
1915
1916 namespace B { function Bar() : () {} }
1917 "},
1918 &expect![[r#"
1919 namespace namespace3 {
1920 function item1() : () {}
1921 function item2() : () { open namespace4; item4(); }
1922 }
1923
1924 namespace namespace4 { function item4() : () {} }
1925 "#]],
1926 );
1927}
1928
1929#[test]
1930fn local_open_shadows_parent_open() {
1931 check(
1932 indoc! {"
1933 namespace A {
1934 open B;
1935 function Foo() : () { open C; Bar(); }
1936 }
1937
1938 namespace B { function Bar() : () {} }
1939 namespace C { function Bar() : () {} }
1940 "},
1941 &expect![[r#"
1942 namespace namespace3 {
1943 open namespace4;
1944 function item1() : () { open namespace5; item5(); }
1945 }
1946
1947 namespace namespace4 { function item3() : () {} }
1948 namespace namespace5 { function item5() : () {} }
1949 "#]],
1950 );
1951}
1952
1953#[test]
1954fn update_array_index_var() {
1955 check(
1956 indoc! {"
1957 namespace A {
1958 function Foo() : () {
1959 let xs = [2];
1960 let i = 0;
1961 let ys = xs w/ i <- 3;
1962 }
1963 }
1964 "},
1965 &expect![[r#"
1966 namespace namespace3 {
1967 function item1() : () {
1968 let local11 = [2];
1969 let local16 = 0;
1970 let local20 = local11 w/ local16 <- 3;
1971 }
1972 }
1973 "#]],
1974 );
1975}
1976
1977#[test]
1978fn update_array_index_expr() {
1979 check(
1980 indoc! {"
1981 namespace A {
1982 function Foo() : () {
1983 let xs = [2];
1984 let i = 0;
1985 let ys = xs w/ i + 1 <- 3;
1986 }
1987 }
1988 "},
1989 &expect![[r#"
1990 namespace namespace3 {
1991 function item1() : () {
1992 let local11 = [2];
1993 let local16 = 0;
1994 let local20 = local11 w/ local16 + 1 <- 3;
1995 }
1996 }
1997 "#]],
1998 );
1999}
2000
2001#[test]
2002fn update_udt_known_field_name() {
2003 check(
2004 indoc! {"
2005 namespace A {
2006 newtype Pair = (First : Int, Second : Int);
2007
2008 function Foo() : () {
2009 let p = Pair(1, 2);
2010 let q = p w/ First <- 3;
2011 }
2012 }
2013 "},
2014 &expect![[r#"
2015 namespace namespace3 {
2016 newtype item1 = (First : Int, Second : Int);
2017
2018 function item2() : () {
2019 let local24 = item1(1, 2);
2020 let local34 = local24 w/ First <- 3;
2021 }
2022 }
2023 "#]],
2024 );
2025}
2026
2027#[test]
2028fn update_udt_known_field_name_expr() {
2029 check(
2030 indoc! {"
2031 namespace A {
2032 newtype Pair = (First : Int, Second : Int);
2033
2034 function Foo() : () {
2035 let p = Pair(1, 2);
2036 let q = p w/ First + 1 <- 3;
2037 }
2038 }
2039 "},
2040 &expect![[r#"
2041 namespace namespace3 {
2042 newtype item1 = (First : Int, Second : Int);
2043
2044 function item2() : () {
2045 let local24 = item1(1, 2);
2046 let local34 = local24 w/ First + 1 <- 3;
2047 }
2048 }
2049
2050 // NotFound("First", Span { lo: 138, hi: 143 })
2051 "#]],
2052 );
2053}
2054
2055#[test]
2056fn update_udt_unknown_field_name() {
2057 check(
2058 indoc! {"
2059 namespace A {
2060 newtype Pair = (First : Int, Second : Int);
2061
2062 function Foo() : () {
2063 let p = Pair(1, 2);
2064 let q = p w/ Third <- 3;
2065 }
2066 }
2067 "},
2068 &expect![[r#"
2069 namespace namespace3 {
2070 newtype item1 = (First : Int, Second : Int);
2071
2072 function item2() : () {
2073 let local24 = item1(1, 2);
2074 let local34 = local24 w/ Third <- 3;
2075 }
2076 }
2077 "#]],
2078 );
2079}
2080
2081#[test]
2082fn update_udt_unknown_field_name_known_global() {
2083 check(
2084 indoc! {"
2085 namespace A {
2086 newtype Pair = (First : Int, Second : Int);
2087
2088 function Third() : () {}
2089
2090 function Foo() : () {
2091 let p = Pair(1, 2);
2092 let q = p w/ Third <- 3;
2093 }
2094 }
2095 "},
2096 &expect![[r#"
2097 namespace namespace3 {
2098 newtype item1 = (First : Int, Second : Int);
2099
2100 function item2() : () {}
2101
2102 function item3() : () {
2103 let local30 = item1(1, 2);
2104 let local40 = local30 w/ Third <- 3;
2105 }
2106 }
2107 "#]],
2108 );
2109}
2110
2111#[test]
2112fn unknown_namespace() {
2113 check(
2114 indoc! {"
2115 namespace A {
2116 import Std.Fake.*;
2117 }
2118 "},
2119 &expect![[r#"
2120 namespace namespace3 {
2121 import Std.Fake.*;
2122 }
2123
2124 // GlobImportNamespaceNotFound("Fake", Span { lo: 25, hi: 33 })
2125 "#]],
2126 );
2127}
2128
2129#[test]
2130fn empty_namespace_works() {
2131 check(
2132 indoc! {"
2133 namespace A {
2134 open B;
2135 function foo(): Unit{}
2136 }
2137 namespace B {}
2138 "},
2139 &expect![[r#"
2140 namespace namespace3 {
2141 open namespace4;
2142 function item1(): Unit{}
2143 }
2144 namespace namespace4 {}
2145 "#]],
2146 );
2147}
2148
2149#[test]
2150fn cyclic_namespace_dependency_supported() {
2151 check(
2152 indoc! {"
2153 namespace A {
2154 open B;
2155 operation Foo() : Unit {
2156 Bar();
2157 }
2158 }
2159 namespace B {
2160 open A;
2161 operation Bar() : Unit {
2162 Foo();
2163 }
2164 }
2165 "},
2166 &expect![[r#"
2167 namespace namespace3 {
2168 open namespace4;
2169 operation item1() : Unit {
2170 item3();
2171 }
2172 }
2173 namespace namespace4 {
2174 open namespace3;
2175 operation item3() : Unit {
2176 item1();
2177 }
2178 }
2179 "#]],
2180 );
2181}
2182
2183#[test]
2184fn bind_items_in_repeat() {
2185 check(
2186 indoc! {"
2187 namespace A {
2188 operation B() : Unit {
2189 repeat {
2190 function C() : Unit {}
2191 } until false
2192 fixup {
2193 function D() : Unit {}
2194 }
2195 }
2196 }
2197 "},
2198 &expect![[r#"
2199 namespace namespace3 {
2200 operation item1() : Unit {
2201 repeat {
2202 function item2() : Unit {}
2203 } until false
2204 fixup {
2205 function item3() : Unit {}
2206 }
2207 }
2208 }
2209 "#]],
2210 );
2211}
2212
2213#[test]
2214fn bind_items_in_qubit_use_block() {
2215 check(
2216 indoc! {"
2217 namespace A {
2218 operation B() : Unit {
2219 use q = Qubit() {
2220 function C() : Unit {}
2221 }
2222 }
2223 }
2224 "},
2225 &expect![[r#"
2226 namespace namespace3 {
2227 operation item1() : Unit {
2228 use local13 = Qubit() {
2229 function item2() : Unit {}
2230 }
2231 }
2232 }
2233 "#]],
2234 );
2235}
2236
2237#[test]
2238fn use_bound_item_in_another_bound_item() {
2239 check(
2240 indoc! {"
2241 namespace A {
2242 function B() : Unit {
2243 function C() : Unit {
2244 D();
2245 }
2246 function D() : Unit {}
2247 }
2248 }
2249 "},
2250 &expect![[r#"
2251 namespace namespace3 {
2252 function item1() : Unit {
2253 function item2() : Unit {
2254 item3();
2255 }
2256 function item3() : Unit {}
2257 }
2258 }
2259 "#]],
2260 );
2261}
2262
2263#[test]
2264fn use_unbound_generic() {
2265 check(
2266 indoc! {"
2267 namespace A {
2268 function B<'T>(x: 'U) : 'U {
2269 x
2270 }
2271 }
2272 "},
2273 &expect![[r#"
2274 namespace namespace3 {
2275 function item1<param0>(local9: 'U) : 'U {
2276 local9
2277 }
2278 }
2279
2280 // NotFound("'U", Span { lo: 36, hi: 38 })
2281 // NotFound("'U", Span { lo: 42, hi: 44 })
2282 "#]],
2283 );
2284}
2285
2286#[test]
2287fn resolve_local_generic() {
2288 check(
2289 indoc! {"
2290 namespace A {
2291 function B<'T>(x: 'T) : 'T {
2292 x
2293 }
2294 }
2295 "},
2296 &expect![[r#"
2297 namespace namespace3 {
2298 function item1<param0>(local9: param0) : param0 {
2299 local9
2300 }
2301 }
2302 "#]],
2303 );
2304}
2305
2306#[test]
2307fn dropped_base_callable_from_unrestricted() {
2308 check_with_capabilities(
2309 indoc! {"
2310 namespace A {
2311 @Config(Base)
2312 function Dropped() : Unit {}
2313
2314 function B() : Unit {
2315 Dropped();
2316 }
2317 }
2318 "},
2319 TargetCapabilityFlags::all(),
2320 &expect![[r#"
2321 namespace namespace3 {
2322 @Config(Base)
2323 function Dropped() : Unit {}
2324
2325 function item1() : Unit {
2326 Dropped();
2327 }
2328 }
2329
2330 // NotAvailable("Dropped", "A.Dropped", Span { lo: 100, hi: 107 })
2331 "#]],
2332 );
2333}
2334
2335#[test]
2336fn dropped_base_callable_from_adaptive() {
2337 check_with_capabilities(
2338 indoc! {"
2339 namespace A {
2340 @Config(Base)
2341 function Dropped() : Unit {}
2342
2343 function B() : Unit {
2344 Dropped();
2345 }
2346 }
2347 "},
2348 TargetCapabilityFlags::Adaptive,
2349 &expect![[r#"
2350 namespace namespace3 {
2351 @Config(Base)
2352 function Dropped() : Unit {}
2353
2354 function item1() : Unit {
2355 Dropped();
2356 }
2357 }
2358
2359 // NotAvailable("Dropped", "A.Dropped", Span { lo: 100, hi: 107 })
2360 "#]],
2361 );
2362}
2363
2364#[test]
2365fn dropped_not_base_callable_from_base() {
2366 check_with_capabilities(
2367 indoc! {"
2368 namespace A {
2369 @Config(not Base)
2370 function Dropped() : Unit {}
2371
2372 function B() : Unit {
2373 Dropped();
2374 }
2375 }
2376 "},
2377 TargetCapabilityFlags::empty(),
2378 &expect![[r#"
2379 namespace namespace3 {
2380 @Config(not Base)
2381 function Dropped() : Unit {}
2382
2383 function item1() : Unit {
2384 Dropped();
2385 }
2386 }
2387
2388 // NotAvailable("Dropped", "A.Dropped", Span { lo: 104, hi: 111 })
2389 "#]],
2390 );
2391}
2392
2393#[test]
2394fn resolved_not_base_callable_from_adaptive() {
2395 check_with_capabilities(
2396 indoc! {"
2397 namespace A {
2398 @Config(not Base)
2399 function Dropped() : Unit {}
2400
2401 function B() : Unit {
2402 Dropped();
2403 }
2404 }
2405 "},
2406 TargetCapabilityFlags::Adaptive,
2407 &expect![[r#"
2408 namespace namespace3 {
2409 @Config(not Base)
2410 function item1() : Unit {}
2411
2412 function item2() : Unit {
2413 item1();
2414 }
2415 }
2416 "#]],
2417 );
2418}
2419
2420#[test]
2421fn dropped_base_and_not_base_callable_from_base() {
2422 check_with_capabilities(
2423 indoc! {"
2424 namespace A {
2425 @Config(Base)
2426 @Config(not Base)
2427 function Dropped() : Unit {}
2428
2429 function B() : Unit {
2430 Dropped();
2431 }
2432 }
2433 "},
2434 TargetCapabilityFlags::empty(),
2435 &expect![[r#"
2436 namespace namespace3 {
2437 @Config(Base)
2438 @Config(not Base)
2439 function Dropped() : Unit {}
2440
2441 function item1() : Unit {
2442 Dropped();
2443 }
2444 }
2445
2446 // NotAvailable("Dropped", "A.Dropped", Span { lo: 122, hi: 129 })
2447 "#]],
2448 );
2449}
2450
2451#[test]
2452fn resolved_not_unrestricted_callable_from_base() {
2453 check_with_capabilities(
2454 indoc! {"
2455 namespace A {
2456 @Config(not Unrestricted)
2457 function Dropped() : Unit {}
2458
2459 function B() : Unit {
2460 Dropped();
2461 }
2462 }
2463 "},
2464 TargetCapabilityFlags::empty(),
2465 &expect![[r#"
2466 namespace namespace3 {
2467 @Config(not Unrestricted)
2468 function item1() : Unit {}
2469
2470 function item2() : Unit {
2471 item1();
2472 }
2473 }
2474 "#]],
2475 );
2476}
2477
2478#[test]
2479fn resolved_not_unrestricted_callable_from_adaptive() {
2480 check_with_capabilities(
2481 indoc! {"
2482 namespace A {
2483 @Config(not Unrestricted)
2484 function Dropped() : Unit {}
2485
2486 function B() : Unit {
2487 Dropped();
2488 }
2489 }
2490 "},
2491 TargetCapabilityFlags::Adaptive,
2492 &expect![[r#"
2493 namespace namespace3 {
2494 @Config(not Unrestricted)
2495 function item1() : Unit {}
2496
2497 function item2() : Unit {
2498 item1();
2499 }
2500 }
2501 "#]],
2502 );
2503}
2504
2505#[test]
2506fn dropped_not_unrestricted_callable_from_unrestricted() {
2507 check_with_capabilities(
2508 indoc! {"
2509 namespace A {
2510 @Config(not Unrestricted)
2511 function Dropped() : Unit {}
2512
2513 function B() : Unit {
2514 Dropped();
2515 }
2516 }
2517 "},
2518 TargetCapabilityFlags::all(),
2519 &expect![[r#"
2520 namespace namespace3 {
2521 @Config(not Unrestricted)
2522 function Dropped() : Unit {}
2523
2524 function item1() : Unit {
2525 Dropped();
2526 }
2527 }
2528
2529 // NotAvailable("Dropped", "A.Dropped", Span { lo: 112, hi: 119 })
2530 "#]],
2531 );
2532}
2533
2534#[test]
2535fn resolved_adaptive_callable_from_adaptive() {
2536 check_with_capabilities(
2537 indoc! {"
2538 namespace A {
2539 @Config(Adaptive)
2540 function Dropped() : Unit {}
2541
2542 function B() : Unit {
2543 Dropped();
2544 }
2545 }
2546 "},
2547 TargetCapabilityFlags::Adaptive,
2548 &expect![[r#"
2549 namespace namespace3 {
2550 @Config(Adaptive)
2551 function item1() : Unit {}
2552
2553 function item2() : Unit {
2554 item1();
2555 }
2556 }
2557 "#]],
2558 );
2559}
2560
2561#[test]
2562fn resolved_adaptive_callable_from_unrestricted() {
2563 check_with_capabilities(
2564 indoc! {"
2565 namespace A {
2566 @Config(Adaptive)
2567 function Dropped() : Unit {}
2568
2569 function B() : Unit {
2570 Dropped();
2571 }
2572 }
2573 "},
2574 TargetCapabilityFlags::all(),
2575 &expect![[r#"
2576 namespace namespace3 {
2577 @Config(Adaptive)
2578 function item1() : Unit {}
2579
2580 function item2() : Unit {
2581 item1();
2582 }
2583 }
2584 "#]],
2585 );
2586}
2587
2588#[test]
2589fn dropped_not_higher_level_callable_from_unrestricted() {
2590 check_with_capabilities(
2591 indoc! {"
2592 namespace A {
2593 @Config(not HigherLevelConstructs)
2594 function Dropped() : Unit {}
2595
2596 function B() : Unit {
2597 Dropped();
2598 }
2599 }
2600 "},
2601 TargetCapabilityFlags::all(),
2602 &expect![[r#"
2603 namespace namespace3 {
2604 @Config(not HigherLevelConstructs)
2605 function Dropped() : Unit {}
2606
2607 function item1() : Unit {
2608 Dropped();
2609 }
2610 }
2611
2612 // NotAvailable("Dropped", "A.Dropped", Span { lo: 121, hi: 128 })
2613 "#]],
2614 );
2615}
2616
2617#[test]
2618fn resolved_not_higher_level_callable_from_adaptive() {
2619 check_with_capabilities(
2620 indoc! {"
2621 namespace A {
2622 @Config(not HigherLevelConstructs)
2623 function Dropped() : Unit {}
2624
2625 function B() : Unit {
2626 Dropped();
2627 }
2628 }
2629 "},
2630 TargetCapabilityFlags::Adaptive,
2631 &expect![[r#"
2632 namespace namespace3 {
2633 @Config(not HigherLevelConstructs)
2634 function item1() : Unit {}
2635
2636 function item2() : Unit {
2637 item1();
2638 }
2639 }
2640 "#]],
2641 );
2642}
2643
2644#[test]
2645fn resolved_not_higher_level_callable_from_base() {
2646 check_with_capabilities(
2647 indoc! {"
2648 namespace A {
2649 @Config(not HigherLevelConstructs)
2650 function Dropped() : Unit {}
2651
2652 function B() : Unit {
2653 Dropped();
2654 }
2655 }
2656 "},
2657 TargetCapabilityFlags::empty(),
2658 &expect![[r#"
2659 namespace namespace3 {
2660 @Config(not HigherLevelConstructs)
2661 function item1() : Unit {}
2662
2663 function item2() : Unit {
2664 item1();
2665 }
2666 }
2667 "#]],
2668 );
2669}
2670
2671#[test]
2672fn dropped_not_higher_level_and_adaptive_callable_from_base() {
2673 check_with_capabilities(
2674 indoc! {"
2675 namespace A {
2676 @Config(Adaptive)
2677 @Config(not HigherLevelConstructs)
2678 function Dropped() : Unit {}
2679
2680 function B() : Unit {
2681 Dropped();
2682 }
2683 }
2684 "},
2685 TargetCapabilityFlags::empty(),
2686 &expect![[r#"
2687 namespace namespace3 {
2688 @Config(Adaptive)
2689 @Config(not HigherLevelConstructs)
2690 function Dropped() : Unit {}
2691
2692 function item1() : Unit {
2693 Dropped();
2694 }
2695 }
2696
2697 // NotAvailable("Dropped", "A.Dropped", Span { lo: 143, hi: 150 })
2698 "#]],
2699 );
2700}
2701
2702#[test]
2703fn dropped_not_higher_level_and_adaptive_callable_from_unrestricted() {
2704 check_with_capabilities(
2705 indoc! {"
2706 namespace A {
2707 @Config(Adaptive)
2708 @Config(not HigherLevelConstructs)
2709 function Dropped() : Unit {}
2710
2711 function B() : Unit {
2712 Dropped();
2713 }
2714 }
2715 "},
2716 TargetCapabilityFlags::all(),
2717 &expect![[r#"
2718 namespace namespace3 {
2719 @Config(Adaptive)
2720 @Config(not HigherLevelConstructs)
2721 function Dropped() : Unit {}
2722
2723 function item1() : Unit {
2724 Dropped();
2725 }
2726 }
2727
2728 // NotAvailable("Dropped", "A.Dropped", Span { lo: 143, hi: 150 })
2729 "#]],
2730 );
2731}
2732
2733#[test]
2734fn resolved_not_higher_level_and_adaptive_callable_from_adaptive() {
2735 check_with_capabilities(
2736 indoc! {"
2737 namespace A {
2738 @Config(Adaptive)
2739 @Config(not HigherLevelConstructs)
2740 function Dropped() : Unit {}
2741
2742 function B() : Unit {
2743 Dropped();
2744 }
2745 }
2746 "},
2747 TargetCapabilityFlags::Adaptive,
2748 &expect![[r#"
2749 namespace namespace3 {
2750 @Config(Adaptive)
2751 @Config(not HigherLevelConstructs)
2752 function item1() : Unit {}
2753
2754 function item2() : Unit {
2755 item1();
2756 }
2757 }
2758 "#]],
2759 );
2760}
2761
2762#[test]
2763fn dropped_floating_point_from_adaptive() {
2764 check_with_capabilities(
2765 indoc! {"
2766 namespace A {
2767 @Config(FloatingPointComputations)
2768 function Dropped() : Double {}
2769
2770 function B() : Unit {
2771 Dropped();
2772 }
2773 }
2774 "},
2775 TargetCapabilityFlags::Adaptive,
2776 &expect![[r#"
2777 namespace namespace3 {
2778 @Config(FloatingPointComputations)
2779 function Dropped() : Double {}
2780
2781 function item1() : Unit {
2782 Dropped();
2783 }
2784 }
2785
2786 // NotAvailable("Dropped", "A.Dropped", Span { lo: 123, hi: 130 })
2787 "#]],
2788 );
2789}
2790
2791#[test]
2792fn resolved_adaptive_and_integer_from_adaptive_and_integer() {
2793 check_with_capabilities(
2794 indoc! {"
2795 namespace A {
2796 @Config(Adaptive)
2797 @Config(IntegerComputations)
2798 function Dropped() : Double {}
2799
2800 function B() : Unit {
2801 Dropped();
2802 }
2803 }
2804 "},
2805 TargetCapabilityFlags::Adaptive | TargetCapabilityFlags::IntegerComputations,
2806 &expect![[r#"
2807 namespace namespace3 {
2808 @Config(Adaptive)
2809 @Config(IntegerComputations)
2810 function item1() : Double {}
2811
2812 function item2() : Unit {
2813 item1();
2814 }
2815 }
2816 "#]],
2817 );
2818}
2819
2820#[test]
2821fn multiple_definition_dropped_is_not_found() {
2822 check(
2823 indoc! {"
2824 namespace A {
2825 @Config(Adaptive)
2826 operation B() : Unit {}
2827 @Config(Base)
2828 operation B() : Unit {}
2829 @Config(Base)
2830 operation C() : Unit {}
2831 @Config(Adaptive)
2832 operation C() : Unit {}
2833 }
2834 namespace D {
2835 operation E() : Unit {
2836 B();
2837 C();
2838 }
2839 operation F() : Unit {
2840 open A;
2841 B();
2842 C();
2843 }
2844 }
2845 "},
2846 &expect![[r#"
2847 namespace namespace3 {
2848 @Config(Adaptive)
2849 operation item1() : Unit {}
2850 @Config(Base)
2851 operation B() : Unit {}
2852 @Config(Base)
2853 operation C() : Unit {}
2854 @Config(Adaptive)
2855 operation item2() : Unit {}
2856 }
2857 namespace namespace4 {
2858 operation item4() : Unit {
2859 B();
2860 C();
2861 }
2862 operation item5() : Unit {
2863 open namespace3;
2864 item1();
2865 item2();
2866 }
2867 }
2868
2869 // NotFound("B", Span { lo: 257, hi: 258 })
2870 // NotFound("C", Span { lo: 270, hi: 271 })
2871 "#]],
2872 );
2873}
2874
2875#[test]
2876fn disallow_duplicate_intrinsic() {
2877 check(
2878 indoc! {"
2879 namespace A {
2880 operation B() : Unit {
2881 body intrinsic;
2882 }
2883 }
2884 namespace B {
2885 operation B() : Unit {
2886 body intrinsic;
2887 }
2888 }
2889 "},
2890 &expect![[r#"
2891 namespace namespace3 {
2892 operation item1() : Unit {
2893 body intrinsic;
2894 }
2895 }
2896 namespace namespace4 {
2897 operation item3() : Unit {
2898 body intrinsic;
2899 }
2900 }
2901
2902 // DuplicateIntrinsic("B", Span { lo: 101, hi: 102 })
2903 "#]],
2904 );
2905}
2906
2907#[test]
2908fn disallow_duplicate_intrinsic_and_non_intrinsic_collision() {
2909 check(
2910 indoc! {"
2911 namespace A {
2912 internal operation C() : Unit {
2913 body intrinsic;
2914 }
2915 }
2916 namespace B {
2917 operation C() : Unit {}
2918 }
2919 namespace B {
2920 operation C() : Unit {
2921 body intrinsic;
2922 }
2923 }
2924 "},
2925 &expect![[r#"
2926 namespace namespace3 {
2927 internal operation item1() : Unit {
2928 body intrinsic;
2929 }
2930 }
2931 namespace namespace4 {
2932 operation item3() : Unit {}
2933 }
2934 namespace namespace4 {
2935 operation item5() : Unit {
2936 body intrinsic;
2937 }
2938 }
2939
2940 // Duplicate("C", "B", Span { lo: 154, hi: 155 })
2941 // DuplicateIntrinsic("C", Span { lo: 154, hi: 155 })
2942 "#]],
2943 );
2944}
2945
2946#[test]
2947fn disallow_duplicate_intrinsic_and_simulatableintrinsic() {
2948 check(
2949 indoc! {"
2950 namespace A {
2951 operation C() : Unit {
2952 body intrinsic;
2953 }
2954 }
2955 namespace B {
2956 @SimulatableIntrinsic()
2957 operation C() : Unit {}
2958 }
2959 "},
2960 &expect![[r#"
2961 namespace namespace3 {
2962 operation item1() : Unit {
2963 body intrinsic;
2964 }
2965 }
2966 namespace namespace4 {
2967 @SimulatableIntrinsic()
2968 operation item3() : Unit {}
2969 }
2970
2971 // DuplicateIntrinsic("C", Span { lo: 129, hi: 130 })
2972 "#]],
2973 );
2974}
2975
2976#[allow(clippy::cast_possible_truncation)]
2977fn check_locals(input: &str, expect: &Expect) {
2978 let parts = input.split('↘').collect::<Vec<_>>();
2979 assert_eq!(
2980 parts.len(),
2981 2,
2982 "input must contain exactly one cursor marker"
2983 );
2984 let cursor_offset = parts[0].len() as u32;
2985 let source = parts.join("");
2986
2987 let (_, _, locals, _, _) = compile(
2988 &source,
2989 LanguageFeatures::default(),
2990 TargetCapabilityFlags::all(),
2991 );
2992
2993 let locals = locals.get_all_at_offset(cursor_offset);
2994 let actual = locals.iter().fold(String::new(), |mut output, l| {
2995 let _ = writeln!(
2996 output,
2997 "{} ({})",
2998 l.name,
2999 match l.kind {
3000 LocalKind::Item(item_id) => item_id.to_string(),
3001 LocalKind::TyParam(param_id) => format!("ty_param {param_id}"),
3002 LocalKind::Var(node_id) => format!("var {node_id}"),
3003 }
3004 );
3005 output
3006 });
3007
3008 expect.assert_eq(&actual);
3009}
3010
3011#[test]
3012fn get_locals_vars() {
3013 check_locals(
3014 indoc! {"
3015 namespace Foo {
3016 function A() : Int {
3017 let x = 0;
3018
3019 let y = 0;
3020 }
3021 }
3022 "},
3023 &expect![[r#"
3024 x (var 13)
3025 "#]],
3026 );
3027}
3028
3029#[test]
3030fn get_locals_vars_shadowing_same_scope() {
3031 check_locals(
3032 indoc! {r#"
3033 namespace Foo {
3034 function A() : Int {
3035 let x = 0;
3036 let x = "foo";
3037
3038 }
3039 }
3040 "#},
3041 &expect![[r#"
3042 x (var 17)
3043 "#]],
3044 );
3045}
3046
3047#[test]
3048fn get_locals_vars_parent_scope() {
3049 check_locals(
3050 indoc! {r#"
3051 namespace Foo {
3052 function A() : Int {
3053 let x = 0;
3054 {
3055 let y = 0;
3056
3057 }
3058 }
3059 }
3060 "#},
3061 &expect![[r#"
3062 y (var 20)
3063 x (var 13)
3064 "#]],
3065 );
3066}
3067
3068#[test]
3069fn get_locals_params() {
3070 check_locals(
3071 indoc! {r#"
3072 namespace Foo {
3073 function A(x : Int) : Int {
3074
3075 }
3076 }
3077 "#},
3078 &expect![[r#"
3079 x (var 8)
3080 "#]],
3081 );
3082}
3083
3084#[test]
3085fn get_locals_spec_params() {
3086 check_locals(
3087 indoc! {"
3088 namespace Foo {
3089 operation A(q : Qubit) : (Qubit[], Qubit) {
3090 controlled (cs, ...) {
3091
3092 }
3093 }
3094 }
3095 "},
3096 &expect![[r#"
3097 cs (var 23)
3098 q (var 8)
3099 "#]],
3100 );
3101}
3102
3103#[test]
3104fn get_locals_before_binding() {
3105 check_locals(
3106 indoc! {"
3107 namespace Foo {
3108 function A() : Unit {
3109 let y = 0;
3110 let x = { ↘ };
3111 }
3112 }
3113 "},
3114 &expect![[r#"
3115 y (var 13)
3116 "#]],
3117 );
3118}
3119
3120#[test]
3121fn get_locals_lambda_params() {
3122 check_locals(
3123 indoc! {"
3124 namespace Foo {
3125 function A() : Unit {
3126 let y = 0;
3127 let f = x -> { ↘ };
3128 }
3129 }
3130 "},
3131 &expect![[r#"
3132 x (var 20)
3133 y (var 13)
3134 "#]],
3135 );
3136}
3137
3138#[test]
3139fn get_locals_for_loop() {
3140 check_locals(
3141 indoc! {"
3142 namespace Foo {
3143 function A() : Unit {
3144 for x in 0..1 {
3145
3146 }
3147 }
3148 }
3149 "},
3150 &expect![[r#"
3151 x (var 14)
3152 "#]],
3153 );
3154}
3155
3156#[test]
3157fn get_locals_for_loop_before_binding() {
3158 check_locals(
3159 indoc! {"
3160 namespace Foo {
3161 function A() : Unit {
3162 for x in 0..{ ↘ } {
3163 }
3164 }
3165 }
3166 "},
3167 &expect![""],
3168 );
3169}
3170
3171#[test]
3172fn get_locals_items() {
3173 check_locals(
3174 indoc! {"
3175 namespace Foo {
3176 function A() : Unit {
3177
3178 function B() : Unit {}
3179 newtype Bar = String;
3180 }
3181 }
3182 "},
3183 &expect![[r#"
3184 Bar (Item 3)
3185 B (Item 2)
3186 "#]],
3187 );
3188}
3189
3190#[test]
3191fn get_locals_local_item_hide_parent_scope_variables() {
3192 check_locals(
3193 indoc! {"
3194 namespace Foo {
3195 function A() : Unit {
3196 let x = 3;
3197 function B() : Unit {
3198 let y = 3;
3199
3200 }
3201 }
3202 }
3203 "},
3204 &expect![[r#"
3205 y (var 26)
3206 B (Item 2)
3207 "#]],
3208 );
3209}
3210
3211#[test]
3212fn get_locals_shadow_parent_scope() {
3213 check_locals(
3214 indoc! {r#"
3215 namespace Foo {
3216 function A() : Unit {
3217 let x = "foo";
3218 {
3219 let x = 0;
3220
3221 }
3222 }
3223 }
3224 "#},
3225 &expect![[r#"
3226 x (var 20)
3227 "#]],
3228 );
3229}
3230
3231#[test]
3232fn get_locals_type_params() {
3233 check_locals(
3234 indoc! {"
3235 namespace Foo {
3236 function A<'T>(t: 'T) : Unit {
3237 {
3238
3239 }
3240 }
3241 }
3242 "},
3243 &expect![[r#"
3244 t (var 9)
3245 'T (ty_param 0)
3246 "#]],
3247 );
3248}
3249
3250#[test]
3251fn get_locals_block_scope_boundary() {
3252 check_locals(
3253 indoc! {"
3254 namespace Foo {
3255 function A() : Int {
3256 {
3257 let x = 0;
3258 }↘
3259 }
3260 }
3261 "},
3262 &expect![""],
3263 );
3264}
3265
3266#[test]
3267fn get_locals_block_scope_boundary_begin() {
3268 check_locals(
3269 indoc! {"
3270 namespace Foo {
3271 function A() : Int {
3272 ↘{
3273 function Bar(): Unit {}
3274 }
3275 }
3276 }
3277 "},
3278 &expect![""],
3279 );
3280}
3281
3282#[test]
3283fn use_after_scope() {
3284 check(
3285 indoc! {"
3286 namespace Foo {
3287 function A() : Unit {
3288 {
3289 let x = 42;
3290 }
3291 x; // x should not be accessible here
3292 }
3293 }
3294 "},
3295 &expect![[r#"
3296 namespace namespace3 {
3297 function item1() : Unit {
3298 {
3299 let local16 = 42;
3300 }
3301 x; // x should not be accessible here
3302 }
3303 }
3304
3305 // NotFound("x", Span { lo: 94, hi: 95 })
3306 "#]],
3307 );
3308}
3309
3310#[test]
3311fn nested_function_definition() {
3312 check(
3313 indoc! {"
3314 namespace Foo {
3315 function A() : Unit {
3316 function B() : Unit {
3317 function C() : Unit {}
3318 C();
3319 }
3320 B();
3321 }
3322 }
3323 "},
3324 &expect![[r#"
3325 namespace namespace3 {
3326 function item1() : Unit {
3327 function item2() : Unit {
3328 function item3() : Unit {}
3329 item3();
3330 }
3331 item2();
3332 }
3333 }
3334 "#]],
3335 );
3336}
3337
3338#[test]
3339fn variable_in_nested_blocks() {
3340 check(
3341 indoc! {"
3342 namespace Foo {
3343 function A() : Unit {
3344 {
3345 let x = 10;
3346 {
3347 let y = x + 5;
3348 y; // Should be accessible
3349 }
3350 y; // Should not be accessible
3351 }
3352 }
3353 }
3354 "},
3355 &expect![[r#"
3356 namespace namespace3 {
3357 function item1() : Unit {
3358 {
3359 let local16 = 10;
3360 {
3361 let local23 = local16 + 5;
3362 local23; // Should be accessible
3363 }
3364 y; // Should not be accessible
3365 }
3366 }
3367 }
3368
3369 // NotFound("y", Span { lo: 190, hi: 191 })
3370 "#]],
3371 );
3372}
3373
3374#[test]
3375fn function_call_with_namespace_alias() {
3376 check(
3377 indoc! {"
3378 namespace Foo {
3379 function A() : Unit {}
3380 }
3381 namespace Bar {
3382 open Foo as F;
3383 function B() : Unit {
3384 F.A();
3385 }
3386 }
3387 "},
3388 &expect![[r#"
3389 namespace namespace3 {
3390 function item1() : Unit {}
3391 }
3392 namespace namespace4 {
3393 open namespace3 as F;
3394 function item3() : Unit {
3395 item1();
3396 }
3397 }
3398 "#]],
3399 );
3400}
3401
3402#[test]
3403fn type_alias_in_function_scope() {
3404 check(
3405 indoc! {"
3406 namespace Foo {
3407 function A() : Unit {
3408 newtype MyInt = Int;
3409 let x : MyInt = MyInt(5);
3410 }
3411 function B() : Unit {
3412 let z: MyInt = MyInt(5); // this should be a different type (and unresolved)
3413 }
3414 }
3415 "},
3416 &expect![[r#"
3417 namespace namespace3 {
3418 function item1() : Unit {
3419 newtype item3 = Int;
3420 let local20 : item3 = item3(5);
3421 }
3422 function item2() : Unit {
3423 let local40: MyInt = MyInt(5); // this should be a different type (and unresolved)
3424 }
3425 }
3426
3427 // NotFound("MyInt", Span { lo: 152, hi: 157 })
3428 // NotFound("MyInt", Span { lo: 160, hi: 165 })
3429 "#]],
3430 );
3431}
3432
3433#[test]
3434fn lambda_inside_lambda() {
3435 check(
3436 indoc! {"
3437 namespace Foo {
3438 function A() : Unit {
3439 let f = () -> {
3440 let g = (x) -> x + 1;
3441 g(10);
3442 };
3443 f();
3444 }
3445 }
3446 "},
3447 &expect![[r#"
3448 namespace namespace3 {
3449 function item1() : Unit {
3450 let local13 = () -> {
3451 let local20 = (local24) -> local24 + 1;
3452 local20(10);
3453 };
3454 local13();
3455 }
3456 }
3457 "#]],
3458 );
3459}
3460
3461#[test]
3462fn nested_namespaces_with_same_function_name() {
3463 check(
3464 indoc! {"
3465 namespace Foo {
3466 function A() : Unit {}
3467 }
3468 namespace Bar {
3469 function A() : Unit {}
3470 function B() : Unit {
3471 Foo.A();
3472 A(); // Should call Bar.A without needing to qualify
3473 }
3474 }
3475 "},
3476 &expect![[r#"
3477 namespace namespace3 {
3478 function item1() : Unit {}
3479 }
3480 namespace namespace4 {
3481 function item3() : Unit {}
3482 function item4() : Unit {
3483 item1();
3484 item3(); // Should call Bar.A without needing to qualify
3485 }
3486 }
3487 "#]],
3488 );
3489}
3490
3491#[test]
3492fn newtype_with_invalid_field_type() {
3493 check(
3494 indoc! {"
3495 namespace Foo {
3496 newtype Complex = (Re: Real, Im: Imaginary); // Imaginary is not a valid type
3497 }
3498 "},
3499 &expect![[r#"
3500 namespace namespace3 {
3501 newtype item1 = (Re: Real, Im: Imaginary); // Imaginary is not a valid type
3502 }
3503
3504 // NotFound("Real", Span { lo: 43, hi: 47 })
3505 // NotFound("Imaginary", Span { lo: 53, hi: 62 })
3506 "#]],
3507 );
3508}
3509
3510#[test]
3511fn newtype_with_tuple_destructuring() {
3512 check(
3513 indoc! {"
3514 namespace Foo {
3515 newtype Pair = (First: Int, Second: Int);
3516 function Destructure(pair: Pair) : Int {
3517 let (first, second) = pair;
3518 first + second
3519 }
3520 }
3521 "},
3522 &expect![[r#"
3523 namespace namespace3 {
3524 newtype item1 = (First: Int, Second: Int);
3525 function item2(local21: item1) : Int {
3526 let (local32, local34) = local21;
3527 local32 + local34
3528 }
3529 }
3530 "#]],
3531 );
3532}
3533
3534#[test]
3535fn items_resolve_according_to_implicit_hierarchy() {
3536 check(
3537 indoc! {"
3538namespace Foo {
3539 @EntryPoint()
3540 function Main(): Int {
3541 Foo()
3542 }
3543
3544 function Foo() : Int {
3545 Bar.Baz.Quux()
3546 }
3547}
3548
3549namespace Foo.Bar.Baz {
3550 function Quux() : Int { 6 }
3551}
3552"},
3553 &expect![[r#"
3554 namespace namespace3 {
3555 @EntryPoint()
3556 function item1(): Int {
3557 item2()
3558 }
3559
3560 function item2() : Int {
3561 item4()
3562 }
3563 }
3564
3565 namespace namespace5 {
3566 function item4() : Int { 6 }
3567 }
3568 "#]],
3569 );
3570}
3571
3572#[test]
3573fn basic_hierarchical_namespace() {
3574 check(
3575 indoc! {"
3576 namespace Foo.Bar.Baz {
3577 operation Quux() : Unit {}
3578 }
3579 namespace A {
3580 open Foo;
3581 operation Main() : Unit {
3582 Bar.Baz.Quux();
3583 }
3584 }
3585 namespace B {
3586 open Foo.Bar;
3587 operation Main() : Unit {
3588 Baz.Quux();
3589 }
3590 }"},
3591 &expect![[r#"
3592 namespace namespace5 {
3593 operation item1() : Unit {}
3594 }
3595 namespace namespace6 {
3596 open namespace3;
3597 operation item3() : Unit {
3598 item1();
3599 }
3600 }
3601 namespace namespace7 {
3602 open namespace4;
3603 operation item5() : Unit {
3604 item1();
3605 }
3606 }"#]],
3607 );
3608}
3609
3610#[test]
3611fn test_katas_shadowing_use_case() {
3612 check(
3613 indoc! {"namespace Kata {
3614 operation ApplyX() : Unit {
3615 // Do nothing.
3616 }
3617}
3618
3619namespace Kata.Verification {
3620 operation CheckSolution() : Bool {
3621 let _ = Kata.ApplyX();
3622 let _ = ApplyX();
3623 }
3624
3625 operation ApplyX() : Unit {}
3626}
3627" },
3628 &expect![[r#"
3629 namespace namespace3 {
3630 operation item1() : Unit {
3631 // Do nothing.
3632 }
3633 }
3634
3635 namespace namespace4 {
3636 operation item3() : Bool {
3637 let _ = item1();
3638 let _ = item4();
3639 }
3640
3641 operation item4() : Unit {}
3642 }
3643 "#]],
3644 );
3645}
3646
3647#[test]
3648fn open_can_access_parent_scope() {
3649 check(
3650 indoc! {r#"
3651namespace Foo.Bar {
3652 operation Hello() : Unit {
3653
3654 }
3655}
3656
3657namespace Foo {
3658 open Bar;
3659 @EntryPoint()
3660 operation Main() : Unit {
3661 Hello();
3662 }
3663}"#},
3664 &expect![[r#"
3665 namespace namespace4 {
3666 operation item1() : Unit {
3667
3668 }
3669 }
3670
3671 namespace namespace3 {
3672 open Bar;
3673 @EntryPoint()
3674 operation item3() : Unit {
3675 item1();
3676 }
3677 }"#]],
3678 );
3679}
3680
3681#[test]
3682fn test_export_statement() {
3683 check(
3684 indoc! {"namespace Foo {
3685 operation ApplyX() : Unit {
3686 }
3687 export ApplyX;
3688}
3689" },
3690 &expect![[r#"
3691 namespace namespace3 {
3692 operation item1() : Unit {
3693 }
3694 export item1;
3695 }
3696 "#]],
3697 );
3698}
3699
3700#[test]
3701fn test_complicated_nested_export_statement() {
3702 check(
3703 indoc! {
3704"
3705
3706namespace Foo {
3707 export Foo.Bar.Baz.Quux.HelloWorld;
3708}
3709namespace Foo.Bar.Baz.Quux {
3710 function HelloWorld() : Unit {}
3711}
3712
3713namespace Foo.Bar {
3714 export Baz.Quux.HelloWorld;
3715}
3716
3717namespace Foo.Bar.Baz {
3718 export Quux.HelloWorld;
3719}
3720
3721namespace Foo.Bar.Graule {
3722 // HelloWorld should be available from all namespaces
3723 operation Main() : Unit {
3724 Foo.Bar.Baz.Quux.HelloWorld();
3725 Foo.Bar.Baz.HelloWorld();
3726 Foo.Bar.HelloWorld();
3727 Foo.HelloWorld();
3728 open Foo;
3729 HelloWorld();
3730 }
3731 // and we should be able to re-export it
3732 export Foo.HelloWorld;
3733}" },
3734 &expect![[r#"
3735
3736 namespace namespace3 {
3737 export item2;
3738 }
3739 namespace namespace6 {
3740 function item2() : Unit {}
3741 }
3742
3743 namespace namespace4 {
3744 export item2;
3745 }
3746
3747 namespace namespace5 {
3748 export item2;
3749 }
3750
3751 namespace namespace7 {
3752 // HelloWorld should be available from all namespaces
3753 operation item6() : Unit {
3754 item2();
3755 item2();
3756 item2();
3757 item2();
3758 open namespace3;
3759 item2();
3760 }
3761 // and we should be able to re-export it
3762 export item2;
3763 }"#]],
3764 );
3765}
3766
3767#[test]
3768fn exports_aware_of_opens() {
3769 check(
3770 indoc! {r#"
3771 namespace Foo {
3772 operation F() : Unit {}
3773 }
3774 namespace Main {
3775 open Foo;
3776 export F;
3777 }
3778 "# },
3779 &expect![[r#"
3780 namespace namespace3 {
3781 operation item1() : Unit {}
3782 }
3783 namespace namespace4 {
3784 open namespace3;
3785 export item1;
3786 }
3787 "#]],
3788 );
3789}
3790
3791#[test]
3792fn export_symbol_and_call_it() {
3793 check(
3794 indoc! {
3795"
3796namespace Foo {
3797 export Foo.Bar.Baz.Quux.Function;
3798}
3799namespace Foo.Bar.Baz.Quux {
3800 function Function() : Unit {}
3801}
3802
3803namespace Main {
3804 open Foo;
3805 operation Main() : Unit {
3806 Foo.Function();
3807 Function();
3808 }
3809}" },
3810 &expect![[r#"
3811 namespace namespace3 {
3812 export item2;
3813 }
3814 namespace namespace6 {
3815 function item2() : Unit {}
3816 }
3817
3818 namespace namespace7 {
3819 open namespace3;
3820 operation item4() : Unit {
3821 item2();
3822 item2();
3823 }
3824 }"#]],
3825 );
3826}
3827
3828#[test]
3829fn multiple_exports() {
3830 check(
3831 indoc! {"
3832 namespace Foo {
3833 operation ApplyX() : Unit {}
3834 operation ApplyY() : Unit {}
3835 }
3836 namespace Main {
3837 import Foo.ApplyX as X, Foo.ApplyY as Y;
3838 operation Main() : Unit {
3839 X();
3840 Y();
3841 }
3842 }
3843 "},
3844 &expect![[r#"
3845 namespace namespace3 {
3846 operation item1() : Unit {}
3847 operation item2() : Unit {}
3848 }
3849 namespace namespace4 {
3850 import item1, item2;
3851 operation item4() : Unit {
3852 item1();
3853 item2();
3854 }
3855 }
3856 "#]],
3857 );
3858}
3859
3860#[test]
3861fn no_exports() {
3862 check(
3863 indoc! {"
3864 namespace Foo {
3865 operation ApplyX() : Unit {}
3866 }
3867 namespace Main {
3868 open Foo;
3869 operation Main() : Unit {
3870 ApplyX();
3871 }
3872 }
3873 "},
3874 &expect![[r#"
3875 namespace namespace3 {
3876 operation item1() : Unit {}
3877 }
3878 namespace namespace4 {
3879 open namespace3;
3880 operation item3() : Unit {
3881 item1();
3882 }
3883 }
3884 "#]],
3885 );
3886}
3887
3888#[test]
3889fn export_non_existent_symbol() {
3890 check(
3891 indoc! {"
3892 namespace Foo {
3893 export NonExistent;
3894 }
3895 "},
3896 &expect![[r#"
3897 namespace namespace3 {
3898 export NonExistent;
3899 }
3900
3901 // NotFound("NonExistent", Span { lo: 27, hi: 38 })
3902 "#]],
3903 );
3904}
3905
3906#[test]
3907fn export_symbol_from_nested_namespace() {
3908 check(
3909 indoc! {"
3910 namespace Foo.Bar {
3911 operation ApplyX() : Unit {}
3912 }
3913 namespace Foo {
3914 export Bar.ApplyX;
3915 }
3916 namespace Main {
3917 open Foo;
3918 operation Main() : Unit {
3919 Bar.ApplyX();
3920 }
3921 }
3922 "},
3923 &expect![[r#"
3924 namespace namespace4 {
3925 operation item1() : Unit {}
3926 }
3927 namespace namespace3 {
3928 export item1;
3929 }
3930 namespace namespace5 {
3931 open namespace3;
3932 operation item4() : Unit {
3933 item1();
3934 }
3935 }
3936 "#]],
3937 );
3938}
3939
3940#[test]
3941fn disallow_exporting_local_vars() {
3942 check(
3943 indoc! {"
3944 namespace Foo {
3945 operation Main() : Unit {
3946 let x = 5;
3947 }
3948 export x;
3949 }
3950 "},
3951 &expect![[r#"
3952 namespace namespace3 {
3953 operation item1() : Unit {
3954 let local13 = 5;
3955 }
3956 export x;
3957 }
3958
3959 // NotFound("x", Span { lo: 82, hi: 83 })
3960 "#]],
3961 );
3962}
3963
3964#[test]
3965fn export_non_item() {
3966 check(
3967 indoc! {"
3968 namespace Bar {}
3969 namespace Foo {
3970 operation Main() : Unit {
3971 }
3972 export Unit;
3973
3974 }
3975 "},
3976 &expect![[r#"
3977 namespace namespace3 {}
3978 namespace namespace4 {
3979 operation item2() : Unit {
3980 }
3981 export Unit;
3982
3983 }
3984 "#]],
3985 );
3986}
3987
3988#[test]
3989fn export_udt() {
3990 check(
3991 indoc! {"
3992 namespace Foo {
3993 newtype Pair = (First: Int, Second: Int);
3994 export Pair;
3995 }
3996 namespace Main {
3997 open Foo;
3998 operation Main() : Unit {
3999 Pair(1, 2);
4000 }
4001 }
4002 "},
4003 &expect![[r#"
4004 namespace namespace3 {
4005 newtype item1 = (First: Int, Second: Int);
4006 export item1;
4007 }
4008 namespace namespace4 {
4009 open namespace3;
4010 operation item3() : Unit {
4011 item1(1, 2);
4012 }
4013 }
4014 "#]],
4015 );
4016}
4017
4018#[test]
4019fn export_with_alias() {
4020 check(
4021 indoc! {"
4022 namespace Foo {
4023 operation ApplyX() : Unit {}
4024 export ApplyX as SomeAlias;
4025 }
4026 namespace Main {
4027 open Foo;
4028 operation Main() : Unit {
4029 SomeAlias();
4030 }
4031 }
4032 "},
4033 &expect![[r#"
4034 namespace namespace3 {
4035 operation item1() : Unit {}
4036 export item1;
4037 }
4038 namespace namespace4 {
4039 open namespace3;
4040 operation item3() : Unit {
4041 item1();
4042 }
4043 }
4044 "#]],
4045 );
4046}
4047
4048#[test]
4049fn multiple_exports_with_aliases() {
4050 check(
4051 indoc! {"
4052 namespace Foo {
4053 operation ApplyX() : Unit {}
4054 operation ApplyY() : Unit {}
4055 export ApplyX as SomeAlias, ApplyY as AnotherAlias;
4056 }
4057 namespace Main {
4058 open Foo;
4059 operation Main() : Unit {
4060 SomeAlias();
4061 AnotherAlias();
4062 }
4063 }
4064 "},
4065 &expect![[r#"
4066 namespace namespace3 {
4067 operation item1() : Unit {}
4068 operation item2() : Unit {}
4069 export item1, item2;
4070 }
4071 namespace namespace4 {
4072 open namespace3;
4073 operation item4() : Unit {
4074 item1();
4075 item2();
4076 }
4077 }
4078 "#]],
4079 );
4080}
4081
4082#[test]
4083fn aliased_exports_call_with_qualified_paths() {
4084 check(
4085 indoc! {"
4086 namespace Foo {
4087 operation ApplyX() : Unit {}
4088 operation ApplyY() : Unit {}
4089 export ApplyX as SomeAlias, ApplyY as AnotherAlias;
4090 }
4091 namespace Main {
4092 open Foo;
4093 operation Main() : Unit {
4094 Foo.SomeAlias();
4095 Foo.AnotherAlias();
4096 }
4097 }
4098 "},
4099 &expect![[r#"
4100 namespace namespace3 {
4101 operation item1() : Unit {}
4102 operation item2() : Unit {}
4103 export item1, item2;
4104 }
4105 namespace namespace4 {
4106 open namespace3;
4107 operation item4() : Unit {
4108 item1();
4109 item2();
4110 }
4111 }
4112 "#]],
4113 );
4114}
4115
4116#[test]
4117fn reexport_from_full_path_with_alias() {
4118 check(
4119 indoc! {"
4120 namespace Foo {
4121 operation ApplyX() : Unit {}
4122 export ApplyX as SomeAlias;
4123 }
4124 namespace Main {
4125 open Foo;
4126 export Foo.SomeAlias as AnotherAlias;
4127 }
4128 "},
4129 &expect![[r#"
4130 namespace namespace3 {
4131 operation item1() : Unit {}
4132 export item1;
4133 }
4134 namespace namespace4 {
4135 open namespace3;
4136 export item1;
4137 }
4138 "#]],
4139 );
4140}
4141
4142#[test]
4143fn disallow_repeated_exports() {
4144 check(
4145 indoc! {"
4146 namespace Foo {
4147 operation ApplyX() : Unit {}
4148 export ApplyX;
4149 export ApplyX;
4150 }
4151 "},
4152 &expect![[r#"
4153 namespace namespace3 {
4154 operation item1() : Unit {}
4155 export item1;
4156 export item1;
4157 }
4158
4159 // DuplicateExport("ApplyX", Span { lo: 79, hi: 85 })
4160 "#]],
4161 );
4162}
4163
4164#[test]
4165fn disallow_repeated_exports_inline() {
4166 check(
4167 indoc! {"
4168 namespace Foo {
4169 operation ApplyX() : Unit {}
4170 export ApplyX, ApplyX;
4171 }
4172 "},
4173 &expect![[r#"
4174 namespace namespace3 {
4175 operation item1() : Unit {}
4176 export item1, item1;
4177 }
4178
4179 // DuplicateExport("ApplyX", Span { lo: 68, hi: 74 })
4180 "#]],
4181 );
4182}
4183
4184#[test]
4185fn order_of_exports_does_not_matter() {
4186 check(
4187 indoc! {"
4188 namespace Bar {
4189 export Foo.ApplyX;
4190 export ApplyY;
4191 operation ApplyY() : Unit {}
4192 }
4193 namespace Foo {
4194 operation ApplyX() : Unit {}
4195 }
4196
4197 "},
4198 &expect![[r#"
4199 namespace namespace3 {
4200 export item3;
4201 export item1;
4202 operation item1() : Unit {}
4203 }
4204 namespace namespace4 {
4205 operation item3() : Unit {}
4206 }
4207
4208 "#]],
4209 );
4210}
4211
4212#[test]
4213fn export_udt_and_construct_it() {
4214 check(
4215 indoc! {"
4216 namespace Foo {
4217 newtype Pair = (First: Int, Second: Int);
4218 export Pair;
4219 }
4220 namespace Main {
4221 open Foo;
4222 operation Main() : Unit {
4223 let z: Pair = Pair(1, 2);
4224 }
4225 }
4226 "},
4227 &expect![[r#"
4228 namespace namespace3 {
4229 newtype item1 = (First: Int, Second: Int);
4230 export item1;
4231 }
4232 namespace namespace4 {
4233 open namespace3;
4234 operation item3() : Unit {
4235 let local34: item1 = item1(1, 2);
4236 }
4237 }
4238 "#]],
4239 );
4240}
4241#[test]
4242fn import_single_item() {
4243 check(
4244 indoc! {"
4245 namespace Foo {
4246 function Bar() : Unit {}
4247 }
4248 namespace Main {
4249 import Foo.Bar;
4250 operation Main() : Unit {
4251 Bar();
4252 }
4253 }
4254 "},
4255 &expect![[r#"
4256 namespace namespace3 {
4257 function item1() : Unit {}
4258 }
4259 namespace namespace4 {
4260 import item1;
4261 operation item3() : Unit {
4262 item1();
4263 }
4264 }
4265 "#]],
4266 );
4267}
4268
4269#[test]
4270fn import_namespace() {
4271 check(
4272 indoc! {"
4273 namespace Foo.Bar {
4274 function Baz() : Unit {}
4275 }
4276 namespace Main {
4277 import Foo.Bar;
4278 operation Main() : Unit {
4279 Bar.Baz();
4280 }
4281 }
4282 "},
4283 &expect![[r#"
4284 namespace namespace4 {
4285 function item1() : Unit {}
4286 }
4287 namespace namespace5 {
4288 import namespace4;
4289 operation item3() : Unit {
4290 item1();
4291 }
4292 }
4293 "#]],
4294 );
4295}
4296
4297#[test]
4298fn import_non_existent_item() {
4299 check(
4300 indoc! {"
4301 namespace Foo {
4302 }
4303 namespace Main {
4304 import Foo.Bar;
4305 operation Main() : Unit {
4306 Bar();
4307 }
4308 }
4309 "},
4310 &expect![[r#"
4311 namespace namespace3 {
4312 }
4313 namespace namespace4 {
4314 import Foo.Bar;
4315 operation item2() : Unit {
4316 Bar();
4317 }
4318 }
4319
4320 // NotFound("Foo.Bar", Span { lo: 46, hi: 53 })
4321 // NotFound("Bar", Span { lo: 93, hi: 96 })
4322 "#]],
4323 );
4324}
4325
4326#[test]
4327fn import_shadowing() {
4328 check(
4329 indoc! {"
4330 namespace Foo {
4331 function Bar() : Unit {}
4332 }
4333 namespace Main {
4334 function Bar() : Unit {}
4335 import Foo.Bar;
4336 operation Main() : Unit {
4337 Bar();
4338 }
4339 }
4340 "},
4341 &expect![[r#"
4342 namespace namespace3 {
4343 function item1() : Unit {}
4344 }
4345 namespace namespace4 {
4346 function item3() : Unit {}
4347 import item1;
4348 operation item4() : Unit {
4349 item1();
4350 }
4351 }
4352 "#]],
4353 );
4354}
4355
4356#[test]
4357fn import_with_alias() {
4358 check(
4359 indoc! {"
4360 namespace Foo {
4361 function Bar() : Unit {}
4362 }
4363 namespace Main {
4364 import Foo.Bar as Baz;
4365 operation Main() : Unit {
4366 Baz();
4367 }
4368 }
4369 "},
4370 &expect![[r#"
4371 namespace namespace3 {
4372 function item1() : Unit {}
4373 }
4374 namespace namespace4 {
4375 import item1;
4376 operation item3() : Unit {
4377 item1();
4378 }
4379 }
4380 "#]],
4381 );
4382}
4383
4384#[test]
4385fn import_non_item() {
4386 check(
4387 indoc! {"
4388 namespace Main {
4389 import Unit;
4390 operation Main() : Unit {
4391 }
4392 }
4393 "},
4394 &expect![[r#"
4395 namespace namespace3 {
4396 import Unit;
4397 operation item1() : Unit {
4398 }
4399 }
4400 "#]],
4401 );
4402}
4403
4404#[test]
4405fn import_namespace_nested() {
4406 check(
4407 indoc! {"
4408 namespace Foo.Bar.Baz {
4409 operation Quux() : Unit {}
4410 }
4411 namespace Main {
4412 import Foo.Bar;
4413 operation Main() : Unit {
4414 Bar.Baz.Quux();
4415 }
4416 }
4417 "},
4418 &expect![[r#"
4419 namespace namespace5 {
4420 operation item1() : Unit {}
4421 }
4422 namespace namespace6 {
4423 import namespace4;
4424 operation item3() : Unit {
4425 item1();
4426 }
4427 }
4428 "#]],
4429 );
4430}
4431
4432#[test]
4433fn import_single_namespace() {
4434 check(
4435 indoc! {"
4436 namespace Foo {
4437 operation Bar() : Unit {}
4438 }
4439 namespace Main {
4440 import Foo;
4441
4442 operation Main() : Unit {
4443 Foo.Bar();
4444 }
4445 }
4446 "},
4447 &expect![[r#"
4448 namespace namespace3 {
4449 operation item1() : Unit {}
4450 }
4451 namespace namespace4 {
4452 import namespace3;
4453
4454 operation item3() : Unit {
4455 item1();
4456 }
4457 }
4458 "#]],
4459 );
4460}
4461
4462#[test]
4463fn import_shadowing_function() {
4464 check(
4465 indoc! {"
4466 namespace Foo {
4467 operation Bar() : Unit {}
4468 }
4469 namespace Main {
4470 operation Bar() : Unit {}
4471 operation Main() : Unit {
4472 import Foo.Bar;
4473 Bar();
4474 }
4475 }
4476 "},
4477 &expect![[r#"
4478 namespace namespace3 {
4479 operation item1() : Unit {}
4480 }
4481 namespace namespace4 {
4482 operation item3() : Unit {}
4483 operation item4() : Unit {
4484 import item1;
4485 item1();
4486 }
4487 }
4488 "#]],
4489 );
4490}
4491
4492#[test]
4493fn import_non_existent_namespace() {
4494 check(
4495 indoc! {"
4496 namespace Main {
4497 operation Main() : Unit {
4498 import NonExistent;
4499 }
4500 }
4501 "},
4502 &expect![[r#"
4503 namespace namespace3 {
4504 operation item1() : Unit {
4505 import NonExistent;
4506 }
4507 }
4508
4509 // NotFound("NonExistent", Span { lo: 62, hi: 73 })
4510 "#]],
4511 );
4512}
4513
4514#[test]
4515fn import_self() {
4516 check(
4517 indoc! {"
4518 namespace Main {
4519 operation Foo() : Unit {
4520 import Foo;
4521 }
4522 }
4523 "},
4524 &expect![[r#"
4525 namespace namespace3 {
4526 operation item1() : Unit {
4527 import item1;
4528 }
4529 }
4530 "#]],
4531 );
4532}
4533
4534// this should be allowed for jupyter cell re-runnability
4535#[test]
4536fn import_duplicate_symbol() {
4537 check(
4538 indoc! { r#"
4539 namespace Main {
4540 import Foo.Bar.Baz, Foo.Bar.Baz;
4541 }
4542 namespace Foo.Bar {
4543 operation Baz() : Unit {}
4544 }
4545"# },
4546 &expect![[r#"
4547 namespace namespace3 {
4548 import item2, item2;
4549 }
4550 namespace namespace5 {
4551 operation item2() : Unit {}
4552 }
4553 "#]],
4554 );
4555}
4556
4557// this should be allowed for jupyter cell re-runnability
4558#[test]
4559fn import_duplicate_symbol_different_name() {
4560 check(
4561 indoc! { r#"
4562 namespace Main {
4563 import Foo.Bar.Baz, Foo.Bar;
4564 import Bar.Baz;
4565 }
4566 namespace Foo.Bar {
4567 operation Baz() : Unit {}
4568 }
4569"# },
4570 &expect![[r#"
4571 namespace namespace3 {
4572 import item2, namespace5;
4573 import item2;
4574 }
4575 namespace namespace5 {
4576 operation item2() : Unit {}
4577 }
4578 "#]],
4579 );
4580}
4581
4582// this should be allowed for jupyter cell re-runnability
4583#[test]
4584fn disallow_importing_different_items_with_same_name() {
4585 check(
4586 indoc! { r#"
4587 namespace Main {
4588 import Foo.Bar.Baz, Foo.Bar.Baz2 as Baz;
4589 }
4590 namespace Foo.Bar {
4591 operation Baz() : Unit {}
4592 operation Baz2() : Unit {}
4593 }
4594"# },
4595 &expect![[r#"
4596 namespace namespace3 {
4597 import item2, item3;
4598 }
4599 namespace namespace5 {
4600 operation item2() : Unit {}
4601 operation item3() : Unit {}
4602 }
4603
4604 // ImportedDuplicate("Baz", Span { lo: 57, hi: 60 })
4605 "#]],
4606 );
4607}
4608
4609#[test]
4610fn import_takes_precedence_over_local_decl() {
4611 check(
4612 indoc! { r#"
4613 namespace Main {
4614
4615 operation Baz() : Unit {
4616 import Foo.Bar.Baz;
4617 Baz();
4618 }
4619
4620 }
4621
4622 namespace Foo.Bar {
4623 operation Baz() : Unit {}
4624 }
4625"# },
4626 &expect![[r#"
4627 namespace namespace3 {
4628
4629 operation item1() : Unit {
4630 import item3;
4631 item3();
4632 }
4633
4634 }
4635
4636 namespace namespace5 {
4637 operation item3() : Unit {}
4638 }
4639 "#]],
4640 );
4641}
4642
4643#[test]
4644fn import_then_export() {
4645 check(
4646 indoc! {"
4647 namespace Foo {
4648 operation Bar() : Unit {}
4649 }
4650 namespace Main {
4651 import Foo.Bar;
4652 export Bar;
4653 }
4654 "},
4655 &expect![[r#"
4656 namespace namespace3 {
4657 operation item1() : Unit {}
4658 }
4659 namespace namespace4 {
4660 import item1;
4661 export item1;
4662 }
4663 "#]],
4664 );
4665}
4666
4667#[test]
4668fn import_namespace_advanced() {
4669 check(
4670 indoc! {"
4671 namespace A.B.C.D.E {
4672 operation DumpMachine() : Unit {}
4673 }
4674 namespace TestOne {
4675 import A;
4676 operation Main() : Unit {
4677 A.B.C.D.E.DumpMachine();
4678 }
4679 }
4680 namespace TestTwo {
4681 import A.B;
4682 operation Main() : Unit {
4683 B.C.D.E.DumpMachine();
4684 }
4685 }
4686 namespace TestThree {
4687 import A.B.C;
4688 operation Main() : Unit {
4689 C.D.E.DumpMachine();
4690 }
4691 }
4692 namespace TestFour {
4693 import A.B.C.D;
4694 operation Main() : Unit {
4695 D.E.DumpMachine();
4696 }
4697 }
4698 namespace TestFive {
4699 import A.B.C.D.E;
4700 operation Main() : Unit {
4701 E.DumpMachine();
4702 }
4703 }
4704 namespace TestSix {
4705 import A.B.C.D.E.DumpMachine;
4706 operation Main() : Unit {
4707 DumpMachine();
4708 }
4709 }
4710 "},
4711 &expect![[r#"
4712 namespace namespace7 {
4713 operation item1() : Unit {}
4714 }
4715 namespace namespace8 {
4716 import namespace3;
4717 operation item3() : Unit {
4718 item1();
4719 }
4720 }
4721 namespace namespace9 {
4722 import namespace4;
4723 operation item5() : Unit {
4724 item1();
4725 }
4726 }
4727 namespace namespace10 {
4728 import namespace5;
4729 operation item7() : Unit {
4730 item1();
4731 }
4732 }
4733 namespace namespace11 {
4734 import namespace6;
4735 operation item9() : Unit {
4736 item1();
4737 }
4738 }
4739 namespace namespace12 {
4740 import namespace7;
4741 operation item11() : Unit {
4742 item1();
4743 }
4744 }
4745 namespace namespace13 {
4746 import item1;
4747 operation item13() : Unit {
4748 item1();
4749 }
4750 }
4751 "#]],
4752 );
4753}
4754
4755#[test]
4756fn import_namespace_does_not_open_it() {
4757 check(
4758 indoc! {"
4759 namespace Microsoft.Quantum.Diagnostics {
4760 operation DumpMachine() : Unit {}
4761 }
4762 namespace Main {
4763 import Microsoft.Quantum.Diagnostics;
4764 operation Main() : Unit {
4765 Diagnostics.DumpMachine();
4766 DumpMachine();
4767 }
4768 }
4769 "},
4770 &expect![[r#"
4771 namespace namespace5 {
4772 operation item1() : Unit {}
4773 }
4774 namespace namespace6 {
4775 import namespace5;
4776 operation item3() : Unit {
4777 item1();
4778 DumpMachine();
4779 }
4780 }
4781
4782 // NotFound("DumpMachine", Span { lo: 214, hi: 225 })
4783 "#]],
4784 );
4785}
4786
4787#[test]
4788fn invalid_import() {
4789 check(
4790 indoc! {"
4791 namespace Main {
4792 import A.B.C;
4793 operation Main() : Unit {
4794 }
4795 }
4796 "},
4797 &expect![[r#"
4798 namespace namespace3 {
4799 import A.B.C;
4800 operation item1() : Unit {
4801 }
4802 }
4803
4804 // NotFound("A.B.C", Span { lo: 28, hi: 33 })
4805 "#]],
4806 );
4807}
4808
4809#[test]
4810fn export_namespace() {
4811 check(
4812 indoc! {"
4813 namespace Foo {
4814 operation ApplyX() : Unit {}
4815 operation ApplyY() : Unit {}
4816 }
4817 namespace Main {
4818 export Foo;
4819 }
4820 namespace Test {
4821 open Main.Foo;
4822 operation Main() : Unit {
4823 ApplyX();
4824 ApplyY();
4825 }
4826 }
4827 "},
4828 &expect![[r#"
4829 namespace namespace3 {
4830 operation item1() : Unit {}
4831 operation item2() : Unit {}
4832 }
4833 namespace namespace4 {
4834 export item4;
4835 }
4836 namespace namespace5 {
4837 open namespace3;
4838 operation item6() : Unit {
4839 item1();
4840 item2();
4841 }
4842 }
4843 "#]],
4844 );
4845}
4846
4847#[test]
4848fn export_namespace_contains_children() {
4849 check(
4850 indoc! {"
4851 namespace Foo.Bar {
4852 operation ApplyX() : Unit {}
4853 }
4854 namespace Main {
4855 export Foo;
4856 }
4857 namespace Test {
4858 open Main.Foo.Bar;
4859 operation Main() : Unit {
4860 ApplyX();
4861 }
4862 }
4863 "},
4864 &expect![[r#"
4865 namespace namespace4 {
4866 operation item1() : Unit {}
4867 }
4868 namespace namespace5 {
4869 export item3;
4870 }
4871 namespace namespace6 {
4872 open namespace4;
4873 operation item5() : Unit {
4874 item1();
4875 }
4876 }
4877 "#]],
4878 );
4879}
4880
4881#[test]
4882fn export_namespace_cyclic() {
4883 check(
4884 indoc! {"
4885 namespace Foo {
4886 export Bar;
4887 }
4888 namespace Bar {
4889 export Foo;
4890 operation Hello() : Unit {}
4891 }
4892 namespace Main {
4893 open Foo.Bar.Foo.Bar.Foo.Bar;
4894 operation Main() : Unit { Hello(); }
4895 }
4896 "},
4897 &expect![[r#"
4898 namespace namespace3 {
4899 export namespace4;
4900 }
4901 namespace namespace4 {
4902 export item2;
4903 operation item3() : Unit {}
4904 }
4905 namespace namespace5 {
4906 open namespace4;
4907 operation item5() : Unit { item3(); }
4908 }
4909 "#]],
4910 );
4911}
4912
4913#[test]
4914fn export_direct_cycle() {
4915 check(
4916 indoc! {"
4917 namespace Foo {
4918 export Foo;
4919 }
4920
4921 namespace Main {
4922 open Foo.Foo.Foo.Foo.Foo;
4923 operation Main() : Unit { }
4924 }
4925 "},
4926 &expect![[r#"
4927 namespace namespace3 {
4928 export namespace3;
4929 }
4930
4931 namespace namespace4 {
4932 open namespace3;
4933 operation item2() : Unit { }
4934 }
4935 "#]],
4936 );
4937}
4938
4939#[test]
4940fn export_namespace_with_alias() {
4941 check(
4942 indoc! {"
4943 namespace Foo.Bar {
4944 operation ApplyX() : Unit {}
4945 }
4946 namespace Main {
4947 export Foo.Bar as Baz;
4948 }
4949 namespace Test {
4950 open Main.Baz;
4951 operation Main() : Unit {
4952 ApplyX();
4953 Main.Baz.ApplyX();
4954 }
4955 }
4956 "},
4957 &expect![[r#"
4958 namespace namespace4 {
4959 operation item1() : Unit {}
4960 }
4961 namespace namespace5 {
4962 export namespace4;
4963 }
4964 namespace namespace6 {
4965 open namespace4;
4966 operation item5() : Unit {
4967 item1();
4968 item1();
4969 }
4970 }
4971 "#]],
4972 );
4973}
4974
4975#[test]
4976fn import_glob() {
4977 check(
4978 indoc! {"
4979 namespace Foo {
4980 operation ApplyX() : Unit {}
4981 operation ApplyY() : Unit {}
4982 }
4983 namespace Main {
4984 import Foo.*;
4985 operation Main() : Unit {
4986 ApplyX();
4987 ApplyY();
4988 }
4989 }
4990 "},
4991 &expect![[r#"
4992 namespace namespace3 {
4993 operation item1() : Unit {}
4994 operation item2() : Unit {}
4995 }
4996 namespace namespace4 {
4997 import namespace3.*;
4998 operation item4() : Unit {
4999 item1();
5000 item2();
5001 }
5002 }
5003 "#]],
5004 );
5005}
5006
5007#[test]
5008fn import_aliased_glob() {
5009 check(
5010 indoc! {"
5011 namespace Foo {
5012 operation ApplyX() : Unit {}
5013 operation ApplyY() : Unit {}
5014 }
5015 namespace Main {
5016 import Foo as Bar;
5017 operation Main() : Unit {
5018 Bar.ApplyX();
5019 Bar.ApplyY();
5020 }
5021 }
5022 "},
5023 &expect![[r#"
5024 namespace namespace3 {
5025 operation item1() : Unit {}
5026 operation item2() : Unit {}
5027 }
5028 namespace namespace4 {
5029 import namespace3;
5030 operation item4() : Unit {
5031 item1();
5032 item2();
5033 }
5034 }
5035 "#]],
5036 );
5037}
5038
5039#[test]
5040fn disallow_glob_export() {
5041 check(
5042 indoc! {"
5043 namespace Foo {
5044 operation ApplyX() : Unit {}
5045 operation ApplyY() : Unit {}
5046 }
5047 namespace Bar {
5048 export Foo.*;
5049 }
5050 "},
5051 &expect![[r#"
5052 namespace namespace3 {
5053 operation item1() : Unit {}
5054 operation item2() : Unit {}
5055 }
5056 namespace namespace4 {
5057 export namespace3.*;
5058 }
5059
5060 // GlobExportNotSupported(Span { lo: 111, hi: 114 })
5061 "#]],
5062 );
5063}
5064
5065#[test]
5066fn import_glob_in_list() {
5067 check(
5068 indoc! {"
5069 namespace Foo.Bar {
5070 operation ApplyX() : Unit {}
5071 operation ApplyY() : Unit {}
5072 }
5073 namespace Foo.Bar.Baz {
5074 operation ApplyZ() : Unit {}
5075 }
5076 namespace Main {
5077 import Foo.Bar.*, Foo.Bar.Baz.ApplyZ;
5078 operation Main() : Unit {
5079 ApplyX();
5080 ApplyY();
5081 Baz.ApplyZ();
5082 ApplyZ();
5083 }
5084 }
5085 "},
5086 &expect![[r#"
5087 namespace namespace4 {
5088 operation item1() : Unit {}
5089 operation item2() : Unit {}
5090 }
5091 namespace namespace5 {
5092 operation item4() : Unit {}
5093 }
5094 namespace namespace6 {
5095 import namespace4.*, item4;
5096 operation item6() : Unit {
5097 item1();
5098 item2();
5099 item4();
5100 item4();
5101 }
5102 }
5103 "#]],
5104 );
5105}
5106
5107#[test]
5108fn import_glob_in_list_with_alias() {
5109 check(
5110 indoc! {"
5111 namespace Foo.Bar {
5112 operation ApplyX() : Unit {}
5113 operation ApplyY() : Unit {}
5114 }
5115 namespace Foo.Bar.Baz {
5116 operation ApplyZ() : Unit {}
5117 }
5118 namespace Main {
5119 import Foo.Bar as Alias, Foo.Bar.Baz.ApplyZ as Foo;
5120 operation Main() : Unit {
5121 Alias.ApplyX();
5122 Alias.ApplyY();
5123 Alias.Baz.ApplyZ();
5124 Foo();
5125 }
5126 }
5127 "},
5128 &expect![[r#"
5129 namespace namespace4 {
5130 operation item1() : Unit {}
5131 operation item2() : Unit {}
5132 }
5133 namespace namespace5 {
5134 operation item4() : Unit {}
5135 }
5136 namespace namespace6 {
5137 import namespace4, item4;
5138 operation item6() : Unit {
5139 item1();
5140 item2();
5141 item4();
5142 item4();
5143 }
5144 }
5145 "#]],
5146 );
5147}
5148
5149#[test]
5150fn import_newtype() {
5151 check(
5152 indoc! {r#"
5153 namespace Foo {
5154 import Bar.NewType; // no error
5155
5156 operation FooOperation() : Unit {
5157 let x: NewType = NewType("a");
5158 }
5159 }
5160
5161 namespace Bar {
5162 newtype NewType = String;
5163 export NewType;
5164
5165 }"#},
5166 &expect![[r#"
5167 namespace namespace3 {
5168 import item3; // no error
5169
5170 operation item1() : Unit {
5171 let local17: item3 = item3("a");
5172 }
5173 }
5174
5175 namespace namespace4 {
5176 newtype item3 = String;
5177 export item3;
5178
5179 }"#]],
5180 );
5181}
5182
5183#[test]
5184fn disallow_glob_alias_import() {
5185 check(
5186 indoc! {r#"
5187 namespace Bar {}
5188 namespace Main {
5189 import Bar.* as B;
5190 }
5191 "#},
5192 &expect![[r#"
5193 namespace namespace3 {}
5194 namespace namespace4 {
5195 import namespace3;
5196 }
5197
5198 // GlobImportAliasNotSupported { namespace_name: "Bar", alias: "B", span: Span { lo: 45, hi: 55 } }
5199 "#]],
5200 );
5201}
5202
5203#[test]
5204fn glob_import_ns_not_found() {
5205 check(
5206 indoc! {r#"
5207 namespace Main {
5208 import Bar.*;
5209 }
5210 "#},
5211 &expect![[r#"
5212 namespace namespace3 {
5213 import Bar.*;
5214 }
5215
5216 // GlobImportNamespaceNotFound("Bar", Span { lo: 28, hi: 31 })
5217 "#]],
5218 );
5219}
5220
5221#[test]
5222fn allow_export_of_namespace_within_itself() {
5223 check(
5224 indoc! {r#"
5225 namespace Foo {
5226 export Foo;
5227 }
5228 "#},
5229 &expect![[r#"
5230 namespace namespace3 {
5231 export namespace3;
5232 }
5233 "#]],
5234 );
5235}
5236
5237#[test]
5238fn export_of_item_with_same_name_as_namespace_resolves_to_item() {
5239 check(
5240 indoc! {r#"
5241 namespace Foo {
5242 operation Foo() : Unit {}
5243 export Foo;
5244 }
5245 "#},
5246 &expect![[r#"
5247 namespace namespace3 {
5248 operation item1() : Unit {}
5249 export item1;
5250 }
5251 "#]],
5252 );
5253}
5254
5255#[test]
5256fn export_of_item_with_same_name_as_namespace_resolves_to_item_even_when_before_item() {
5257 check(
5258 indoc! {r#"
5259 namespace Foo {
5260 export Foo;
5261 operation Foo() : Unit {}
5262 }
5263 "#},
5264 &expect![[r#"
5265 namespace namespace3 {
5266 export item1;
5267 operation item1() : Unit {}
5268 }
5269 "#]],
5270 );
5271}
5272
5273#[test]
5274fn ty_param_name_is_in_scope() {
5275 check(
5276 indoc! {r#"
5277 namespace Foo {
5278 operation Foo<'T: Eq>(a: 'T) : Unit {
5279 let x: 'T = a;
5280 }
5281 }
5282 "#},
5283 &expect![[r#"
5284 namespace namespace3 {
5285 operation item1<param0: Eq>(local10: param0) : Unit {
5286 let local19: param0 = local10;
5287 }
5288 }
5289 "#]],
5290 );
5291}
5292