Repository: microsoft/qsharp
Pull request #582 (2023-08-14 22:16:41)

Better BP and stepping through behavior
Compilation may generate code that we don't want to step into. This PR up changes the evaluator to continue executing while the current statement does not have a source span mapping. Additionally, the HIR in some passes is updated to either set or default the statement spans depending on whether we want that code to be steppable.

While loops' condition is an expression thus we can't stop on looping at the conditional check without adding expr stepping or creating a pass for while loops that can introduce a NOP statement with a span on the expr.

```
Teleport evaluation     time:   [102.15 µs 102.21 µs 102.29 µs]
                        change: [+0.1592% +0.3292% +0.5028%] (p = 0.00 < 0.05)
                        Change within noise threshold.

Deutsch-Jozsa evaluation
                        time:   [22.519 ms 22.531 ms 22.547 ms]
                        change: [-0.8468% -0.7858% -0.7114%] (p = 0.00 < 0.05)
                        Change within noise threshold.
```


Patch:
diff --git a/compiler/qsc/src/interpret/stateful.rs b/compiler/qsc/src/interpret/stateful.rs
index 6c5ae3ad..2203601b 100644
--- a/compiler/qsc/src/interpret/stateful.rs
+++ b/compiler/qsc/src/interpret/stateful.rs
@@ -29,7 +29,7 @@ use qsc_fir::{
         Block, BlockId, CallableDecl, Expr, ExprId, LocalItemId, Package, PackageId, Pat, PatId,
         Stmt, StmtId,
     },
-    visit::Visitor,
+    visit::{self, Visitor},
 };
 use qsc_frontend::{
     compile::{CompileUnit, PackageStore, Source, SourceMap, TargetProfile},
@@ -629,7 +629,19 @@ impl<'a> BreakpointCollector<'a> {
 impl<'a> Visitor<'a> for BreakpointCollector<'a> {
     fn visit_stmt(&mut self, stmt: StmtId) {
         let stmt_res = self.get_stmt(stmt);
-        self.add_stmt(stmt_res);
+        match stmt_res.kind {
+            qsc_fir::fir::StmtKind::Expr(expr) | qsc_fir::fir::StmtKind::Local(_, _, expr) => {
+                self.add_stmt(stmt_res);
+                visit::walk_expr(self, expr);
+            }
+            qsc_fir::fir::StmtKind::Qubit(_, _, _, block) => match block {
+                Some(block) => visit::walk_block(self, block),
+                None => self.add_stmt(stmt_res),
+            },
+            qsc_fir::fir::StmtKind::Item(_) | qsc_fir::fir::StmtKind::Semi(_) => {
+                self.add_stmt(stmt_res);
+            }
+        };
     }
 
     fn get_block(&mut self, id: BlockId) -> &'a Block {
diff --git a/compiler/qsc_eval/src/lib.rs b/compiler/qsc_eval/src/lib.rs
index ce418a54..d8b7b366 100644
--- a/compiler/qsc_eval/src/lib.rs
+++ b/compiler/qsc_eval/src/lib.rs
@@ -530,10 +530,14 @@ impl State {
                     if let Some(bp) = breakpoints.iter().find(|&bp| *bp == stmt) {
                         StepResult::BreakpointHit(*bp)
                     } else {
+                        if self.current_span == Span::default() {
+                            // if there is no span, we are in generated code, so we should skip
+                            continue;
+                        }
                         // no breakpoint, but we may stop here
                         if step == StepAction::In {
                             StepResult::StepIn
-                        } else if step == StepAction::Next && current_frame == self.call_stack.len()
+                        } else if step == StepAction::Next && current_frame >= self.call_stack.len()
                         {
                             StepResult::Next
                         } else if step == StepAction::Out && current_frame > self.call_stack.len() {
diff --git a/compiler/qsc_passes/src/common.rs b/compiler/qsc_passes/src/common.rs
index 314d5033..d258baba 100644
--- a/compiler/qsc_passes/src/common.rs
+++ b/compiler/qsc_passes/src/common.rs
@@ -58,6 +58,19 @@ impl IdentTemplate {
     }
 
     pub fn gen_id_init(&self, mutability: Mutability, expr: Expr, assigner: &mut Assigner) -> Stmt {
+        Stmt {
+            id: assigner.next_node(),
+            span: Span::default(),
+            kind: StmtKind::Local(mutability, self.gen_pat(assigner), expr),
+        }
+    }
+
+    pub fn gen_steppable_id_init(
+        &self,
+        mutability: Mutability,
+        expr: Expr,
+        assigner: &mut Assigner,
+    ) -> Stmt {
         Stmt {
             id: assigner.next_node(),
             span: self.span,
diff --git a/compiler/qsc_passes/src/loop_unification.rs b/compiler/qsc_passes/src/loop_unification.rs
index b0f0f2f5..9c6ca392 100644
--- a/compiler/qsc_passes/src/loop_unification.rs
+++ b/compiler/qsc_passes/src/loop_unification.rs
@@ -96,7 +96,7 @@ impl LoopUni<'_> {
                 continue_cond_init,
                 Stmt {
                     id: self.assigner.next_node(),
-                    span,
+                    span: Span::default(),
                     kind: StmtKind::Expr(Expr {
                         id: self.assigner.next_node(),
                         span,
@@ -155,7 +155,7 @@ impl LoopUni<'_> {
         );
 
         let index_id = self.gen_ident("index_id", Ty::Prim(Prim::Int), iterable_span);
-        let index_init = index_id.gen_id_init(
+        let index_init = index_id.gen_steppable_id_init(
             Mutability::Mutable,
             Expr {
                 id: self.assigner.next_node(),
@@ -169,7 +169,7 @@ impl LoopUni<'_> {
         let pat_ty = iter.ty.clone();
         let pat_init = Stmt {
             id: self.assigner.next_node(),
-            span,
+            span: iter.span,
             kind: StmtKind::Local(
                 Mutability::Immutable,
                 iter,
@@ -209,7 +209,7 @@ impl LoopUni<'_> {
 
         let while_stmt = Stmt {
             id: self.assigner.next_node(),
-            span,
+            span: Span::default(),
             kind: StmtKind::Expr(Expr {
                 id: self.assigner.next_node(),
                 span,
@@ -244,7 +244,7 @@ impl LoopUni<'_> {
         let range_capture = range_id.gen_id_init(Mutability::Immutable, *iterable, self.assigner);
 
         let index_id = self.gen_ident("index_id", Ty::Prim(Prim::Int), iterable_span);
-        let index_init = index_id.gen_id_init(
+        let index_init = index_id.gen_steppable_id_init(
             Mutability::Mutable,
             range_id.gen_field_access(PrimField::Start, self.assigner),
             self.assigner,
@@ -266,7 +266,7 @@ impl LoopUni<'_> {
 
         let pat_init = Stmt {
             id: self.assigner.next_node(),
-            span,
+            span: iter.span,
             kind: StmtKind::Local(
                 Mutability::Immutable,
                 iter,
@@ -284,7 +284,7 @@ impl LoopUni<'_> {
 
         let while_stmt = Stmt {
             id: self.assigner.next_node(),
-            span,
+            span: Span::default(),
             kind: StmtKind::Expr(Expr {
                 id: self.assigner.next_node(),
                 span,
diff --git a/compiler/qsc_passes/src/replace_qubit_allocation.rs b/compiler/qsc_passes/src/replace_qubit_allocation.rs
index 78795417..f9ff0e65 100644
--- a/compiler/qsc_passes/src/replace_qubit_allocation.rs
+++ b/compiler/qsc_passes/src/replace_qubit_allocation.rs
@@ -464,7 +464,7 @@ fn create_general_alloc_stmt(
     call_expr: Expr,
     array_size: Option<Expr>,
 ) -> Stmt {
-    ident.gen_id_init(
+    ident.gen_steppable_id_init(
         Mutability::Immutable,
         create_qubit_alloc_call_expr(assigner, ident.span, call_expr, array_size),
         assigner,
diff --git a/samples/language/RepeatUntilLoops.qs b/samples/language/RepeatUntilLoops.qs
index 4f4760e7..3fe177b1 100644
--- a/samples/language/RepeatUntilLoops.qs
+++ b/samples/language/RepeatUntilLoops.qs
@@ -15,7 +15,7 @@ namespace MyQuantumApp {
         mutable x = 0;
         repeat {
             set x += 1;
-        } until x < 3;
+        } until x > 3;
 
         // Repeat-Until loop with fixup
         use qubit = Qubit();
diff --git a/vscode/src/common.ts b/vscode/src/common.ts
index 9309d2d2..eaf3beae 100644
--- a/vscode/src/common.ts
+++ b/vscode/src/common.ts
@@ -22,3 +22,7 @@ export interface FileAccessor {
   openPath(path: string): Promise<TextDocument>;
   openUri(uri: Uri): Promise<TextDocument>;
 }
+
+export function basename(path: string): string | undefined {
+  return path.replace(/\/+$/, "").split("/").pop();
+}
diff --git a/vscode/src/debugger/session.ts b/vscode/src/debugger/session.ts
index f447d6d0..3f7a83e5 100644
--- a/vscode/src/debugger/session.ts
+++ b/vscode/src/debugger/session.ts
@@ -22,7 +22,7 @@ import {
   Scope,
 } from "@vscode/debugadapter";
 
-import { FileAccessor } from "../common";
+import { FileAccessor, basename } from "../common";
 import { DebugProtocol } from "@vscode/debugprotocol";
 import {
   IBreakpointSpan,
@@ -35,7 +35,6 @@ import {
 } from "qsharp";
 import { createDebugConsoleEventTarget } from "./output";
 import { ILaunchRequestArguments } from "./types";
-
 const ErrorProgramHasErrors = "program contains compile errors(s): cannot run.";
 const SimulationCompleted = "Q# simulation completed.";
 const ConfigurationDelayMS = 1000;
@@ -565,7 +564,7 @@ export class QscDebugSession extends LoggingDebugSession {
               id,
               f.name,
               new Source(
-                file.uri.path,
+                basename(f.path) ?? f.path,
                 file.uri.toString(true),
                 undefined,
                 undefined,
@@ -594,13 +593,12 @@ export class QscDebugSession extends LoggingDebugSession {
               const start_pos = file.positionAt(f.lo);
               const end_pos = file.positionAt(f.hi);
               const source = new Source(
-                f.path,
+                basename(f.path) ?? f.path,
                 uri.toString(),
                 0,
-                undefined,
+                "internal core/std library",
                 "qsharp-adapter-data"
               ) as DebugProtocol.Source;
-              source.origin = "internal core/std library";
               const sf = new StackFrame(
                 id,
                 f.name,


Test patch:
diff --git a/compiler/qsc/src/interpret/stateful/stepping_tests.rs b/compiler/qsc/src/interpret/stateful/stepping_tests.rs
index 4350a4a3..13d03afa 100644
--- a/compiler/qsc/src/interpret/stateful/stepping_tests.rs
+++ b/compiler/qsc/src/interpret/stateful/stepping_tests.rs
@@ -49,6 +49,8 @@ mod given_interpreter_with_sources {
             expect_next(&mut interpreter);
             expect_next(&mut interpreter);
             expect_next(&mut interpreter);
+            expect_next(&mut interpreter);
+            expect_next(&mut interpreter);
             let expected = "42";
             expect_return(interpreter, expected);
             Ok(())
@@ -85,6 +87,9 @@ mod given_interpreter_with_sources {
             expect_in(&mut interpreter);
             expect_next(&mut interpreter);
             expect_next(&mut interpreter);
+            expect_next(&mut interpreter);
+            expect_next(&mut interpreter);
+            expect_next(&mut interpreter);
             let expected = "42";
             expect_return(interpreter, expected);
             Ok(())
diff --git a/compiler/qsc_passes/src/loop_unification/tests.rs b/compiler/qsc_passes/src/loop_unification/tests.rs
index cbcb3f4d..72dd52b1 100644
--- a/compiler/qsc_passes/src/loop_unification/tests.rs
+++ b/compiler/qsc_passes/src/loop_unification/tests.rs
@@ -50,10 +50,10 @@ fn convert_for_array() {
                         body: SpecDecl 4 [21-131]: Impl:
                             Block 5 [56-131] [Type Unit]:
                                 Stmt 6 [66-125]: Expr: Expr 43 [66-125] [Type Unit]: Expr Block: Block 44 [66-125] [Type Unit]:
-                                    Stmt 18 [75-78]: Local (Immutable):
+                                    Stmt 18 [0-0]: Local (Immutable):
                                         Pat 19 [75-78] [Type (Int)[]]: Bind: Ident 17 [75-78] "@array_id_17"
                                         Expr 10 [75-78] [Type (Int)[]]: Var: Local 3
-                                    Stmt 24 [75-78]: Local (Immutable):
+                                    Stmt 24 [0-0]: Local (Immutable):
                                         Pat 25 [75-78] [Type Int]: Bind: Ident 21 [75-78] "@len_id_21"
                                         Expr 22 [75-78] [Type (Int)[]]: Call:
                                             Expr 20 [75-78] [Type ((Int)[] -> Int)]: Var:
@@ -64,12 +64,12 @@ fn convert_for_array() {
                                     Stmt 28 [75-78]: Local (Mutable):
                                         Pat 29 [75-78] [Type Int]: Bind: Ident 26 [75-78] "@index_id_26"
                                         Expr 27 [75-78] [Type Int]: Lit: Int(0)
-                                    Stmt 41 [66-125]: Expr: Expr 42 [66-125] [Type Unit]: While:
+                                    Stmt 41 [0-0]: Expr: Expr 42 [66-125] [Type Unit]: While:
                                         Expr 38 [75-78] [Type Bool]: BinOp (Lt):
                                             Expr 39 [75-78] [Type Int]: Var: Local 26
                                             Expr 40 [75-78] [Type Int]: Var: Local 21
                                         Block 11 [79-125] [Type Unit]:
-                                            Stmt 30 [66-125]: Local (Immutable):
+                                            Stmt 30 [70-71]: Local (Immutable):
                                                 Pat 8 [70-71] [Type Int]: Bind: Ident 9 [70-71] "i"
                                                 Expr 31 [75-78] [Type Int]: Index:
                                                     Expr 32 [75-78] [Type (Int)[]]: Var: Local 17
@@ -113,10 +113,10 @@ fn convert_for_array_deconstruct() {
                         body: SpecDecl 4 [21-146]: Impl:
                             Block 5 [66-146] [Type Unit]:
                                 Stmt 6 [76-140]: Expr: Expr 46 [76-140] [Type Unit]: Expr Block: Block 47 [76-140] [Type Unit]:
-                                    Stmt 21 [90-93]: Local (Immutable):
+                                    Stmt 21 [0-0]: Local (Immutable):
                                         Pat 22 [90-93] [Type ((Int, Double))[]]: Bind: Ident 20 [90-93] "@array_id_20"
                                         Expr 13 [90-93] [Type ((Int, Double))[]]: Var: Local 3
-                                    Stmt 27 [90-93]: Local (Immutable):
+                                    Stmt 27 [0-0]: Local (Immutable):
                                         Pat 28 [90-93] [Type Int]: Bind: Ident 24 [90-93] "@len_id_24"
                                         Expr 25 [90-93] [Type ((Int, Double))[]]: Call:
                                             Expr 23 [90-93] [Type (((Int, Double))[] -> Int)]: Var:
@@ -127,12 +127,12 @@ fn convert_for_array_deconstruct() {
                                     Stmt 31 [90-93]: Local (Mutable):
                                         Pat 32 [90-93] [Type Int]: Bind: Ident 29 [90-93] "@index_id_29"
                                         Expr 30 [90-93] [Type Int]: Lit: Int(0)
-                                    Stmt 44 [76-140]: Expr: Expr 45 [76-140] [Type Unit]: While:
+                                    Stmt 44 [0-0]: Expr: Expr 45 [76-140] [Type Unit]: While:
                                         Expr 41 [90-93] [Type Bool]: BinOp (Lt):
                                             Expr 42 [90-93] [Type Int]: Var: Local 29
                                             Expr 43 [90-93] [Type Int]: Var: Local 24
                                         Block 14 [94-140] [Type Unit]:
-                                            Stmt 33 [76-140]: Local (Immutable):
+                                            Stmt 33 [80-86]: Local (Immutable):
                                                 Pat 8 [80-86] [Type (Int, Double)]: Tuple:
                                                     Pat 9 [81-82] [Type Int]: Bind: Ident 10 [81-82] "i"
                                                     Pat 11 [84-85] [Type Double]: Bind: Ident 12 [84-85] "d"
@@ -178,7 +178,7 @@ fn convert_for_slice() {
                         body: SpecDecl 4 [21-141]: Impl:
                             Block 5 [56-141] [Type Unit]:
                                 Stmt 6 [66-135]: Expr: Expr 49 [66-135] [Type Unit]: Expr Block: Block 50 [66-135] [Type Unit]:
-                                    Stmt 24 [75-88]: Local (Immutable):
+                                    Stmt 24 [0-0]: Local (Immutable):
                                         Pat 25 [75-88] [Type (Int)[]]: Bind: Ident 23 [75-88] "@array_id_23"
                                         Expr 10 [75-88] [Type (Int)[]]: Index:
                                             Expr 11 [75-78] [Type (Int)[]]: Var: Local 3
@@ -187,7 +187,7 @@ fn convert_for_slice() {
                                                 Expr 14 [82-84] [Type Int]: UnOp (Neg):
                                                     Expr 15 [83-84] [Type Int]: Lit: Int(2)
                                                 Expr 16 [86-87] [Type Int]: Lit: Int(2)
-                                    Stmt 30 [75-88]: Local (Immutable):
+                                    Stmt 30 [0-0]: Local (Immutable):
                                         Pat 31 [75-88] [Type Int]: Bind: Ident 27 [75-88] "@len_id_27"
                                         Expr 28 [75-88] [Type (Int)[]]: Call:
                                             Expr 26 [75-88] [Type ((Int)[] -> Int)]: Var:
@@ -198,12 +198,12 @@ fn convert_for_slice() {
                                     Stmt 34 [75-88]: Local (Mutable):
                                         Pat 35 [75-88] [Type Int]: Bind: Ident 32 [75-88] "@index_id_32"
                                         Expr 33 [75-88] [Type Int]: Lit: Int(0)
-                                    Stmt 47 [66-135]: Expr: Expr 48 [66-135] [Type Unit]: While:
+                                    Stmt 47 [0-0]: Expr: Expr 48 [66-135] [Type Unit]: While:
                                         Expr 44 [75-88] [Type Bool]: BinOp (Lt):
                                             Expr 45 [75-88] [Type Int]: Var: Local 32
                                             Expr 46 [75-88] [Type Int]: Var: Local 27
                                         Block 17 [89-135] [Type Unit]:
-                                            Stmt 36 [66-135]: Local (Immutable):
+                                            Stmt 36 [70-71]: Local (Immutable):
                                                 Pat 8 [70-71] [Type Int]: Bind: Ident 9 [70-71] "i"
                                                 Expr 37 [75-88] [Type Int]: Index:
                                                     Expr 38 [75-88] [Type (Int)[]]: Var: Local 23
@@ -247,7 +247,7 @@ fn convert_for_range() {
                         body: SpecDecl 3 [21-121]: Impl:
                             Block 4 [45-121] [Type Unit]:
                                 Stmt 5 [55-115]: Expr: Expr 59 [55-115] [Type Unit]: Expr Block: Block 60 [55-115] [Type Unit]:
-                                    Stmt 19 [64-68]: Local (Immutable):
+                                    Stmt 19 [0-0]: Local (Immutable):
                                         Pat 20 [64-68] [Type Range]: Bind: Ident 18 [64-68] "@range_id_18"
                                         Expr 9 [64-68] [Type Range]: Range:
                                             Expr 10 [64-65] [Type Int]: Lit: Int(0)
@@ -258,17 +258,17 @@ fn convert_for_range() {
                                         Expr 22 [64-68] [Type Int]: Field:
                                             Expr 23 [64-68] [Type Range]: Var: Local 18
                                             Prim(Start)
-                                    Stmt 29 [64-68]: Local (Immutable):
+                                    Stmt 29 [0-0]: Local (Immutable):
                                         Pat 30 [64-68] [Type Int]: Bind: Ident 26 [64-68] "@step_id_26"
                                         Expr 27 [64-68] [Type Int]: Field:
                                             Expr 28 [64-68] [Type Range]: Var: Local 18
                                             Prim(Step)
-                                    Stmt 34 [64-68]: Local (Immutable):
+                                    Stmt 34 [0-0]: Local (Immutable):
                                         Pat 35 [64-68] [Type Int]: Bind: Ident 31 [64-68] "@end_id_31"
                                         Expr 32 [64-68] [Type Int]: Field:
                                             Expr 33 [64-68] [Type Range]: Var: Local 18
                                             Prim(End)
-                                    Stmt 57 [55-115]: Expr: Expr 58 [55-115] [Type Unit]: While:
+                                    Stmt 57 [0-0]: Expr: Expr 58 [55-115] [Type Unit]: While:
                                         Expr 42 [64-68] [Type Bool]: BinOp (OrL):
                                             Expr 43 [64-68] [Type Bool]: BinOp (AndL):
                                                 Expr 44 [64-68] [Type Bool]: BinOp (Gt):
@@ -285,7 +285,7 @@ fn convert_for_range() {
                                                     Expr 55 [64-68] [Type Int]: Var: Local 21
                                                     Expr 56 [64-68] [Type Int]: Var: Local 31
                                         Block 12 [69-115] [Type Unit]:
-                                            Stmt 36 [55-115]: Local (Immutable):
+                                            Stmt 36 [59-60]: Local (Immutable):
                                                 Pat 7 [59-60] [Type Int]: Bind: Ident 8 [59-60] "i"
                                                 Expr 37 [64-68] [Type Int]: Var: Local 21
                                             Stmt 13 [83-105]: Local (Immutable):
@@ -327,7 +327,7 @@ fn convert_for_reverse_range() {
                         body: SpecDecl 3 [21-125]: Impl:
                             Block 4 [45-125] [Type Unit]:
                                 Stmt 5 [55-119]: Expr: Expr 61 [55-119] [Type Unit]: Expr Block: Block 62 [55-119] [Type Unit]:
-                                    Stmt 21 [64-72]: Local (Immutable):
+                                    Stmt 21 [0-0]: Local (Immutable):
                                         Pat 22 [64-72] [Type Range]: Bind: Ident 20 [64-72] "@range_id_20"
                                         Expr 9 [64-72] [Type Range]: Range:
                                             Expr 10 [64-65] [Type Int]: Lit: Int(4)
@@ -339,17 +339,17 @@ fn convert_for_reverse_range() {
                                         Expr 24 [64-72] [Type Int]: Field:
                                             Expr 25 [64-72] [Type Range]: Var: Local 20
                                             Prim(Start)
-                                    Stmt 31 [64-72]: Local (Immutable):
+                                    Stmt 31 [0-0]: Local (Immutable):
                                         Pat 32 [64-72] [Type Int]: Bind: Ident 28 [64-72] "@step_id_28"
                                         Expr 29 [64-72] [Type Int]: Field:
                                             Expr 30 [64-72] [Type Range]: Var: Local 20
                                             Prim(Step)
-                                    Stmt 36 [64-72]: Local (Immutable):
+                                    Stmt 36 [0-0]: Local (Immutable):
                                         Pat 37 [64-72] [Type Int]: Bind: Ident 33 [64-72] "@end_id_33"
                                         Expr 34 [64-72] [Type Int]: Field:
                                             Expr 35 [64-72] [Type Range]: Var: Local 20
                                             Prim(End)
-                                    Stmt 59 [55-119]: Expr: Expr 60 [55-119] [Type Unit]: While:
+                                    Stmt 59 [0-0]: Expr: Expr 60 [55-119] [Type Unit]: While:
                                         Expr 44 [64-72] [Type Bool]: BinOp (OrL):
                                             Expr 45 [64-72] [Type Bool]: BinOp (AndL):
                                                 Expr 46 [64-72] [Type Bool]: BinOp (Gt):
@@ -366,7 +366,7 @@ fn convert_for_reverse_range() {
                                                     Expr 57 [64-72] [Type Int]: Var: Local 23
                                                     Expr 58 [64-72] [Type Int]: Var: Local 33
                                         Block 14 [73-119] [Type Unit]:
-                                            Stmt 38 [55-119]: Local (Immutable):
+                                            Stmt 38 [59-60]: Local (Immutable):
                                                 Pat 7 [59-60] [Type Int]: Bind: Ident 8 [59-60] "i"
                                                 Expr 39 [64-72] [Type Int]: Var: Local 23
                                             Stmt 15 [87-109]: Local (Immutable):
@@ -408,10 +408,10 @@ fn convert_repeat() {
                         body: SpecDecl 3 [21-126]: Impl:
                             Block 4 [45-126] [Type Unit]:
                                 Stmt 5 [55-120]: Semi: Expr 26 [55-119] [Type Unit]: Expr Block: Block 22 [55-119] [Type Unit]:
-                                    Stmt 16 [115-119]: Local (Mutable):
+                                    Stmt 16 [0-0]: Local (Mutable):
                                         Pat 17 [115-119] [Type Bool]: Bind: Ident 14 [115-119] "@continue_cond_14"
                                         Expr 15 [115-119] [Type Bool]: Lit: Bool(true)
-                                    Stmt 23 [55-119]: Expr: Expr 24 [55-119] [Type Unit]: While:
+                                    Stmt 23 [0-0]: Expr: Expr 24 [55-119] [Type Unit]: While:
                                         Expr 25 [115-119] [Type Bool]: Var: Local 14
                                         Block 7 [62-108] [Type Unit]:
                                             Stmt 8 [76-98]: Local (Immutable):
@@ -457,10 +457,10 @@ fn convert_repeat_fixup() {
                         body: SpecDecl 3 [21-180]: Impl:
                             Block 4 [45-180] [Type Unit]:
                                 Stmt 5 [55-174]: Expr: Expr 35 [55-174] [Type Unit]: Expr Block: Block 31 [55-174] [Type Unit]:
-                                    Stmt 21 [115-119]: Local (Mutable):
+                                    Stmt 21 [0-0]: Local (Mutable):
                                         Pat 22 [115-119] [Type Bool]: Bind: Ident 19 [115-119] "@continue_cond_19"
                                         Expr 20 [115-119] [Type Bool]: Lit: Bool(true)
-                                    Stmt 32 [55-174]: Expr: Expr 33 [55-174] [Type Unit]: While:
+                                    Stmt 32 [0-0]: Expr: Expr 33 [55-174] [Type Unit]: While:
                                         Expr 34 [115-119] [Type Bool]: Var: Local 19
                                         Block 7 [62-108] [Type Unit]:
                                             Stmt 8 [76-98]: Local (Immutable):
@@ -532,17 +532,17 @@ fn convert_repeat_nested() {
                                     Pat 14 [104-105] [Type Bool]: Bind: Ident 15 [104-105] "c"
                                     Expr 16 [108-112] [Type Bool]: Lit: Bool(true)
                                 Stmt 17 [122-395]: Expr: Expr 90 [122-395] [Type Unit]: Expr Block: Block 86 [122-395] [Type Unit]:
-                                    Stmt 76 [291-292]: Local (Mutable):
+                                    Stmt 76 [0-0]: Local (Mutable):
                                         Pat 77 [291-292] [Type Bool]: Bind: Ident 74 [291-292] "@continue_cond_74"
                                         Expr 75 [291-292] [Type Bool]: Lit: Bool(true)
-                                    Stmt 87 [122-395]: Expr: Expr 88 [122-395] [Type Unit]: While:
+                                    Stmt 87 [0-0]: Expr: Expr 88 [122-395] [Type Unit]: While:
                                         Expr 89 [291-292] [Type Bool]: Var: Local 74
                                         Block 19 [129-284] [Type Unit]:
                                             Stmt 20 [143-274]: Expr: Expr 60 [143-274] [Type Unit]: Expr Block: Block 56 [143-274] [Type Unit]:
-                                                Stmt 46 [205-206]: Local (Mutable):
+                                                Stmt 46 [0-0]: Local (Mutable):
                                                     Pat 47 [205-206] [Type Bool]: Bind: Ident 44 [205-206] "@continue_cond_44"
                                                     Expr 45 [205-206] [Type Bool]: Lit: Bool(true)
-                                                Stmt 57 [143-274]: Expr: Expr 58 [143-274] [Type Unit]: While:
+                                                Stmt 57 [0-0]: Expr: Expr 58 [143-274] [Type Unit]: While:
                                                     Expr 59 [205-206] [Type Bool]: Var: Local 44
                                                     Block 22 [150-198] [Type Unit]:
                                                         Stmt 23 [168-184]: Local (Immutable):
@@ -568,10 +568,10 @@ fn convert_repeat_nested() {
                                                 Expr 84 [291-292] [Type Bool]: Var: Local 74
                                                 Expr 85 [307-395] [Type Unit]: Expr Block: Block 34 [307-395] [Type Unit]:
                                                     Stmt 35 [321-385]: Semi: Expr 73 [321-384] [Type Unit]: Expr Block: Block 69 [321-384] [Type Unit]:
-                                                        Stmt 63 [383-384]: Local (Mutable):
+                                                        Stmt 63 [0-0]: Local (Mutable):
                                                             Pat 64 [383-384] [Type Bool]: Bind: Ident 61 [383-384] "@continue_cond_61"
                                                             Expr 62 [383-384] [Type Bool]: Lit: Bool(true)
-                                                        Stmt 70 [321-384]: Expr: Expr 71 [321-384] [Type Unit]: While:
+                                                        Stmt 70 [0-0]: Expr: Expr 71 [321-384] [Type Unit]: While:
                                                             Expr 72 [383-384] [Type Bool]: Var: Local 61
                                                             Block 37 [328-376] [Type Unit]:
                                                                 Stmt 38 [346-362]: Local (Immutable):
diff --git a/compiler/qsc_passes/src/replace_qubit_allocation/tests.rs b/compiler/qsc_passes/src/replace_qubit_allocation/tests.rs
index 48639b8d..deddf0e1 100644
--- a/compiler/qsc_passes/src/replace_qubit_allocation/tests.rs
+++ b/compiler/qsc_passes/src/replace_qubit_allocation/tests.rs
@@ -560,7 +560,7 @@ fn test_early_returns() {
                                                 Expr 39 [106-107] [Type (Unit => Qubit)]: Var: Item 4 (Package 0)
                                                 Expr 41 [106-107] [Type Unit]: Unit
                                         Stmt 18 [131-141]: Semi: Expr 58 [131-140] [Type Unit]: Expr Block: Block 59 [131-140] [Type Unit]:
-                                            Stmt 45 [138-140]: Local (Immutable):
+                                            Stmt 45 [0-0]: Local (Immutable):
                                                 Pat 46 [138-140] [Type Unit]: Bind: Ident 44 [138-140] "@generated_ident_44"
                                                 Expr 20 [138-140] [Type Unit]: Unit
                                             Stmt 48 [106-107]: Semi: Expr 49 [106-107] [Type Unit]: Call:
@@ -573,7 +573,7 @@ fn test_early_returns() {
                                         Stmt 61 [106-107]: Semi: Expr 62 [106-107] [Type Unit]: Call:
                                             Expr 60 [106-107] [Type (Qubit => Unit)]: Var: Item 5 (Package 0)
                                             Expr 63 [106-107] [Type Qubit]: Var: Local 16
-                                Stmt 90 [161-233]: Local (Immutable):
+                                Stmt 90 [0-0]: Local (Immutable):
                                     Pat 91 [161-233] [Type Unit]: Bind: Ident 89 [161-233] "@generated_ident_89"
                                     Expr 22 [161-233] [Type Unit]: If:
                                         Expr 23 [164-169] [Type Bool]: Lit: Bool(false)
@@ -584,7 +584,7 @@ fn test_early_returns() {
                                                     Expr 64 [188-189] [Type (Unit => Qubit)]: Var: Item 4 (Package 0)
                                                     Expr 66 [188-189] [Type Unit]: Unit
                                             Stmt 30 [213-223]: Semi: Expr 83 [213-222] [Type Unit]: Expr Block: Block 84 [213-222] [Type Unit]:
-                                                Stmt 70 [220-222]: Local (Immutable):
+                                                Stmt 70 [0-0]: Local (Immutable):
                                                     Pat 71 [220-222] [Type Unit]: Bind: Ident 69 [220-222] "@generated_ident_69"
                                                     Expr 32 [220-222] [Type Unit]: Unit
                                                 Stmt 73 [188-189]: Semi: Expr 74 [188-189] [Type Unit]: Call:
@@ -600,7 +600,7 @@ fn test_early_returns() {
                                 Stmt 95 [59-60]: Semi: Expr 96 [59-60] [Type Unit]: Call:
                                     Expr 94 [59-60] [Type (Qubit => Unit)]: Var: Item 5 (Package 0)
                                     Expr 97 [59-60] [Type Qubit]: Var: Local 7
-                                Stmt 92 [161-233]: Expr: Expr 93 [161-233] [Type Unit]: Var: Local 89
+                                Stmt 92 [0-0]: Expr: Expr 93 [161-233] [Type Unit]: Var: Local 89
                         adj: <none>
                         ctl: <none>
                         ctl-adj: <none>"#]],
@@ -650,13 +650,13 @@ fn test_end_exprs() {
                                             Expr 34 [127-128] [Type Qubit]: Call:
                                                 Expr 33 [127-128] [Type (Unit => Qubit)]: Var: Item 4 (Package 0)
                                                 Expr 35 [127-128] [Type Unit]: Unit
-                                        Stmt 39 [152-153]: Local (Immutable):
+                                        Stmt 39 [0-0]: Local (Immutable):
                                             Pat 40 [152-153] [Type Int]: Bind: Ident 38 [152-153] "@generated_ident_38"
                                             Expr 26 [152-153] [Type Int]: Lit: Int(3)
                                         Stmt 44 [127-128]: Semi: Expr 45 [127-128] [Type Unit]: Call:
                                             Expr 43 [127-128] [Type (Qubit => Unit)]: Var: Item 5 (Package 0)
                                             Expr 46 [127-128] [Type Qubit]: Var: Local 23
-                                        Stmt 41 [152-153]: Expr: Expr 42 [152-153] [Type Int]: Var: Local 38
+                                        Stmt 41 [0-0]: Expr: Expr 42 [152-153] [Type Int]: Var: Local 38
                                 Stmt 48 [59-60]: Semi: Expr 49 [59-60] [Type Unit]: Call:
                                     Expr 47 [59-60] [Type (Qubit => Unit)]: Var: Item 5 (Package 0)
                                     Expr 50 [59-60] [Type Qubit]: Var: Local 7
@@ -701,13 +701,13 @@ fn test_array_expr() {
                                                 Expr 23 [87-88] [Type Qubit]: Call:
                                                     Expr 22 [87-88] [Type (Unit => Qubit)]: Var: Item 4 (Package 0)
                                                     Expr 24 [87-88] [Type Unit]: Unit
-                                            Stmt 28 [112-113]: Local (Immutable):
+                                            Stmt 28 [0-0]: Local (Immutable):
                                                 Pat 29 [112-113] [Type Int]: Bind: Ident 27 [112-113] "@generated_ident_27"
                                                 Expr 16 [112-113] [Type Int]: Lit: Int(3)
                                             Stmt 33 [87-88]: Semi: Expr 34 [87-88] [Type Unit]: Call:
                                                 Expr 32 [87-88] [Type (Qubit => Unit)]: Var: Item 5 (Package 0)
                                                 Expr 35 [87-88] [Type Qubit]: Var: Local 13
-                                            Stmt 30 [112-113]: Expr: Expr 31 [112-113] [Type Int]: Var: Local 27
+                                            Stmt 30 [0-0]: Expr: Expr 31 [112-113] [Type Int]: Var: Local 27
                                 Stmt 17 [134-144]: Local (Immutable):
                                     Pat 18 [138-139] [Type Int]: Bind: Ident 19 [138-139] "x"
                                     Expr 20 [142-143] [Type Int]: Lit: Int(3)
@@ -751,7 +751,7 @@ fn test_rtrn_expr() {
                                         Expr 20 [58-59] [Type (Unit => Qubit)]: Var: Item 4 (Package 0)
                                         Expr 22 [58-59] [Type Unit]: Unit
                                 Stmt 9 [79-141]: Semi: Expr 49 [79-140] [Type Unit]: Expr Block: Block 50 [79-140] [Type Unit]:
-                                    Stmt 40 [86-140]: Local (Immutable):
+                                    Stmt 40 [0-0]: Local (Immutable):
                                         Pat 41 [86-140] [Type Int]: Bind: Ident 25 [86-140] "@generated_ident_25"
                                         Expr 11 [86-140] [Type Int]: Expr Block: Block 12 [86-140] [Type Int]:
                                             Stmt 29 [104-105]: Local (Immutable):
@@ -759,13 +759,13 @@ fn test_rtrn_expr() {
                                                 Expr 27 [104-105] [Type Qubit]: Call:
                                                     Expr 26 [104-105] [Type (Unit => Qubit)]: Var: Item 4 (Package 0)
                                                     Expr 28 [104-105] [Type Unit]: Unit
-                                            Stmt 32 [129-130]: Local (Immutable):
+                                            Stmt 32 [0-0]: Local (Immutable):
                                                 Pat 33 [129-130] [Type Int]: Bind: Ident 31 [129-130] "@generated_ident_31"
                                                 Expr 18 [129-130] [Type Int]: Lit: Int(3)
                                             Stmt 37 [104-105]: Semi: Expr 38 [104-105] [Type Unit]: Call:
                                                 Expr 36 [104-105] [Type (Qubit => Unit)]: Var: Item 5 (Package 0)
                                                 Expr 39 [104-105] [Type Qubit]: Var: Local 15
-                                            Stmt 34 [129-130]: Expr: Expr 35 [129-130] [Type Int]: Var: Local 31
+                                            Stmt 34 [0-0]: Expr: Expr 35 [129-130] [Type Int]: Var: Local 31
                                     Stmt 43 [58-59]: Semi: Expr 44 [58-59] [Type Unit]: Call:
                                         Expr 42 [58-59] [Type (Qubit => Unit)]: Var: Item 5 (Package 0)
                                         Expr 45 [58-59] [Type Qubit]: Var: Local 7