microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
alex/pythontelem

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc_frontend/src/resolve/tests.rs

5273lines · modecode

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