microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.8.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc_frontend/src/resolve/tests.rs

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