Repository: microsoft/qsharp
Pull request #1560 (2024-05-22 23:30:53)

Run RCA on interpreter creation and propagate errors

github-actions[bot]: ## Benchmark for 9359082
  <details>
    <summary>Click to view benchmark</summary>

| Test | Base         | PR               | % |
|------|--------------|------------------|---|
| Array append evaluation | **334.0±2.78µs** | 337.3±6.57µs | **+0.99%** |
| Array literal evaluation | **189.6±0.97µs** | 192.8±1.71µs | **+1.69%** |
| Array update evaluation | **414.4±2.28µs** | 417.2±2.62µs | **+0.68%** |
| Core + Standard library compilation | 18.7±0.26ms | 18.8±0.55ms | +0.53% |
| Deutsch-Jozsa evaluation | 5.1±0.04ms | 5.1±0.04ms | 0.00% |
| Large file parity evaluation | **33.9±0.07ms** | 34.0±0.46ms | **+0.29%** |
| Large input file compilation | 12.7±0.38ms | 12.8±0.31ms | +0.79% |
| Large input file compilation (interpreter) | **45.6±0.62ms** | 48.0±1.22ms | **+5.26%** |
| Large nested iteration | **32.8±0.14ms** | 33.0±0.36ms | **+0.61%** |
| Perform Runtime Capabilities Analysis (RCA) on Deutsch-Jozsa sample | **1561.2±27.56µs** | 1607.5±165.88µs | **+2.97%** |
| Perform Runtime Capabilities Analysis (RCA) on large file sample | 7.8±0.11ms | 7.8±0.14ms | 0.00% |
| Perform Runtime Capabilities Analysis (RCA) on teleport sample | 1425.1±30.80µs | 1430.1±31.56µs | +0.35% |
| Perform Runtime Capabilities Analysis (RCA) on the core and std libraries | **27.8±0.17ms** | 28.0±0.41ms | **+0.72%** |
| Teleport evaluation | 89.2±3.67µs | 89.4±8.72µs | +0.22% |

  </details>
  

Patch:
diff --git a/compiler/qsc/src/interpret.rs b/compiler/qsc/src/interpret.rs
index 17e456d2..b59e0b65 100644
--- a/compiler/qsc/src/interpret.rs
+++ b/compiler/qsc/src/interpret.rs
@@ -205,6 +205,27 @@ impl Interpreter {
 
         let source_package_id = compiler.source_package_id();
         let package_id = compiler.package_id();
+
+        let package = map_hir_package_to_fir(package_id);
+        if capabilities != TargetCapabilityFlags::all() {
+            let _ = PassContext::run_fir_passes_on_fir(
+                &fir_store,
+                map_hir_package_to_fir(source_package_id),
+                capabilities,
+            )
+            .map_err(|caps_errors| {
+                let source_package = compiler
+                    .package_store()
+                    .get(source_package_id)
+                    .expect("package should exist in the package store");
+
+                caps_errors
+                    .into_iter()
+                    .map(|error| Error::Pass(WithSource::from_map(&source_package.sources, error)))
+                    .collect::<Vec<_>>()
+            })?;
+        }
+
         Ok(Self {
             compiler,
             lines: 0,
@@ -215,7 +236,7 @@ impl Interpreter {
             sim: sim_circuit_backend(),
             quantum_seed: None,
             classical_seed: None,
-            package: map_hir_package_to_fir(package_id),
+            package,
             source_package: map_hir_package_to_fir(source_package_id),
         })
     }
diff --git a/compiler/qsc_partial_eval/src/lib.rs b/compiler/qsc_partial_eval/src/lib.rs
index f8d50f62..259c1724 100644
--- a/compiler/qsc_partial_eval/src/lib.rs
+++ b/compiler/qsc_partial_eval/src/lib.rs
@@ -1256,7 +1256,7 @@ impl<'a> PartialEvaluator<'a> {
             // Qubit allocations and measurements have special handling.
             "__quantum__rt__qubit_allocate" => Ok(self.allocate_qubit()),
             "__quantum__rt__qubit_release" => Ok(self.release_qubit(args_value)),
-            "__quantum__qis__m__body" => Ok(self.measure_qubit(builder::mz_decl(), args_value)),
+            "__quantum__qis__m__body" => Ok(self.measure_qubit(builder::m_decl(), args_value)),
             "__quantum__qis__mresetz__body" => {
                 Ok(self.measure_qubit(builder::mresetz_decl(), args_value))
             }
diff --git a/compiler/qsc_rir/src/builder.rs b/compiler/qsc_rir/src/builder.rs
index 50ae4d09..16cee676 100644
--- a/compiler/qsc_rir/src/builder.rs
+++ b/compiler/qsc_rir/src/builder.rs
@@ -64,9 +64,9 @@ pub fn rx_decl() -> Callable {
 }
 
 #[must_use]
-pub fn mz_decl() -> Callable {
+pub fn m_decl() -> Callable {
     Callable {
-        name: "__quantum__qis__mz__body".to_string(),
+        name: "__quantum__qis__m__body".to_string(),
         input_type: vec![Ty::Qubit, Ty::Result],
         output_type: None,
         body: None,
@@ -185,7 +185,7 @@ pub fn bell_program() -> Program {
     let mut program = Program::default();
     program.callables.insert(CallableId(0), h_decl());
     program.callables.insert(CallableId(1), cx_decl());
-    program.callables.insert(CallableId(2), mz_decl());
+    program.callables.insert(CallableId(2), m_decl());
     program.callables.insert(CallableId(3), array_record_decl());
     program
         .callables
diff --git a/compiler/qsc_rir/src/passes/reindex_qubits.rs b/compiler/qsc_rir/src/passes/reindex_qubits.rs
index 649048e1..6a9e21ca 100644
--- a/compiler/qsc_rir/src/passes/reindex_qubits.rs
+++ b/compiler/qsc_rir/src/passes/reindex_qubits.rs
@@ -32,9 +32,9 @@ struct BlockQubitMap {
 pub fn reindex_qubits(program: &mut Program) {
     validate_assumptions(program);
 
-    let (used_mz, mz_id) = match find_callable(program, "__quantum__qis__mz__body") {
+    let (used_m, m_id) = match find_callable(program, "__quantum__qis__m__body") {
         Some(id) => (true, id),
-        None => (false, add_mz(program)),
+        None => (false, add_m(program)),
     };
     let (used_cx, cx_id) = match find_callable(program, "__quantum__qis__cx__body") {
         Some(id) => (true, id),
@@ -42,8 +42,8 @@ pub fn reindex_qubits(program: &mut Program) {
     };
     let mresetz_id = find_callable(program, "__quantum__qis__mresetz__body");
     let mut pass = ReindexQubitPass {
-        used_mz,
-        mz_id,
+        used_m,
+        m_id,
         used_cx,
         cx_id,
         mresetz_id,
@@ -128,8 +128,8 @@ pub fn reindex_qubits(program: &mut Program) {
         .retain(|id, callable| callable.call_type != CallableType::Reset && Some(id) != mresetz_id);
 
     // If mz or cx were added but not used, remove them.
-    if !pass.used_mz {
-        program.callables.remove(mz_id);
+    if !pass.used_m {
+        program.callables.remove(m_id);
     }
     if !pass.used_cx {
         program.callables.remove(cx_id);
@@ -137,8 +137,8 @@ pub fn reindex_qubits(program: &mut Program) {
 }
 
 struct ReindexQubitPass {
-    used_mz: bool,
-    mz_id: CallableId,
+    used_m: bool,
+    m_id: CallableId,
     used_cx: bool,
     cx_id: CallableId,
     mresetz_id: Option<CallableId>,
@@ -186,7 +186,7 @@ impl ReindexQubitPass {
                         })
                         .collect::<Vec<_>>();
 
-                    if call_id == self.mz_id {
+                    if call_id == self.m_id {
                         // Since the call was to mz, the new qubit replacing this one must be conditionally flipped.
                         // Achieve this by adding a CNOT gate before the mz call.
                         self.used_cx = true;
@@ -203,8 +203,8 @@ impl ReindexQubitPass {
 
                     // If the call was to mresetz, replace with mz.
                     let call_id = if Some(call_id) == self.mresetz_id {
-                        self.used_mz = true;
-                        self.mz_id
+                        self.used_m = true;
+                        self.m_id
                     } else {
                         call_id
                     };
@@ -267,8 +267,8 @@ fn find_callable(program: &Program, name: &str) -> Option<CallableId> {
     None
 }
 
-fn add_mz(program: &mut Program) -> CallableId {
-    let mz_id = CallableId(
+fn add_m(program: &mut Program) -> CallableId {
+    let m_id = CallableId(
         program
             .callables
             .iter()
@@ -277,8 +277,8 @@ fn add_mz(program: &mut Program) -> CallableId {
             .expect("should be at least one callable")
             + 1,
     );
-    program.callables.insert(mz_id, builder::mz_decl());
-    mz_id
+    program.callables.insert(m_id, builder::m_decl());
+    m_id
 }
 
 fn add_cx(program: &mut Program) -> CallableId {


Test patch:
diff --git a/compiler/qsc/src/codegen/tests.rs b/compiler/qsc/src/codegen/tests.rs
index 29505a6c..b94bce96 100644
--- a/compiler/qsc/src/codegen/tests.rs
+++ b/compiler/qsc/src/codegen/tests.rs
@@ -97,7 +97,7 @@ mod base_profile {
               call void @__quantum__qis__rz__body(double 2.0, %Qubit* inttoptr (i64 0 to %Qubit*))
               call void @__quantum__qis__rz__body(double 0.0, %Qubit* inttoptr (i64 0 to %Qubit*))
               call void @__quantum__qis__rz__body(double 1.0, %Qubit* inttoptr (i64 0 to %Qubit*))
-              call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
+              call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
               call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
               ret void
             }
@@ -106,7 +106,7 @@ mod base_profile {
 
             declare void @__quantum__rt__result_record_output(%Result*, i8*)
 
-            declare void @__quantum__qis__mz__body(%Qubit*, %Result*) #1
+            declare void @__quantum__qis__m__body(%Qubit*, %Result*) #1
 
             attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="1" "required_num_results"="1" }
             attributes #1 = { "irreversible" }
@@ -144,8 +144,8 @@ mod base_profile {
 
             define void @ENTRYPOINT__main() #0 {
             block_0:
-              call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
-              call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 1 to %Result*))
+              call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
+              call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 1 to %Result*))
               call void @__quantum__rt__tuple_record_output(i64 2, i8* null)
               call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
               call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 1 to %Result*), i8* null)
@@ -156,7 +156,7 @@ mod base_profile {
 
             declare void @__quantum__rt__result_record_output(%Result*, i8*)
 
-            declare void @__quantum__qis__mz__body(%Qubit*, %Result*) #1
+            declare void @__quantum__qis__m__body(%Qubit*, %Result*) #1
 
             attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="2" "required_num_results"="2" }
             attributes #1 = { "irreversible" }
@@ -199,8 +199,8 @@ mod base_profile {
             block_0:
               call void @__quantum__qis__x__body(%Qubit* inttoptr (i64 0 to %Qubit*))
               call void @__quantum__qis__x__body(%Qubit* inttoptr (i64 1 to %Qubit*))
-              call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
-              call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 1 to %Result*))
+              call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
+              call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 1 to %Result*))
               call void @__quantum__rt__array_record_output(i64 2, i8* null)
               call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
               call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 1 to %Result*), i8* null)
@@ -213,7 +213,7 @@ mod base_profile {
 
             declare void @__quantum__rt__result_record_output(%Result*, i8*)
 
-            declare void @__quantum__qis__mz__body(%Qubit*, %Result*) #1
+            declare void @__quantum__qis__m__body(%Qubit*, %Result*) #1
 
             attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="2" "required_num_results"="2" }
             attributes #1 = { "irreversible" }
@@ -269,7 +269,7 @@ mod adaptive_profile {
               call void @__quantum__qis__rz__body(double 2.0, %Qubit* inttoptr (i64 0 to %Qubit*))
               call void @__quantum__qis__rz__body(double 0.0, %Qubit* inttoptr (i64 0 to %Qubit*))
               call void @__quantum__qis__rz__body(double 1.0, %Qubit* inttoptr (i64 0 to %Qubit*))
-              call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
+              call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
               call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
               ret void
             }
@@ -278,7 +278,7 @@ mod adaptive_profile {
 
             declare void @__quantum__rt__result_record_output(%Result*, i8*)
 
-            declare void @__quantum__qis__mz__body(%Qubit*, %Result*) #1
+            declare void @__quantum__qis__m__body(%Qubit*, %Result*) #1
 
             attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="1" }
             attributes #1 = { "irreversible" }
@@ -323,8 +323,8 @@ mod adaptive_profile {
 
             define void @ENTRYPOINT__main() #0 {
             block_0:
-              call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
-              call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 1 to %Result*))
+              call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
+              call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 1 to %Result*))
               call void @__quantum__rt__tuple_record_output(i64 2, i8* null)
               call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
               call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 1 to %Result*), i8* null)
@@ -335,7 +335,7 @@ mod adaptive_profile {
 
             declare void @__quantum__rt__result_record_output(%Result*, i8*)
 
-            declare void @__quantum__qis__mz__body(%Qubit*, %Result*) #1
+            declare void @__quantum__qis__m__body(%Qubit*, %Result*) #1
 
             attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="2" "required_num_results"="2" }
             attributes #1 = { "irreversible" }
@@ -384,9 +384,9 @@ mod adaptive_profile {
             define void @ENTRYPOINT__main() #0 {
             block_0:
               call void @__quantum__qis__x__body(%Qubit* inttoptr (i64 0 to %Qubit*))
-              call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
+              call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
               call void @__quantum__qis__x__body(%Qubit* inttoptr (i64 1 to %Qubit*))
-              call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 1 to %Result*))
+              call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 1 to %Result*))
               call void @__quantum__rt__array_record_output(i64 2, i8* null)
               call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
               call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 1 to %Result*), i8* null)
@@ -399,7 +399,7 @@ mod adaptive_profile {
 
             declare void @__quantum__rt__result_record_output(%Result*, i8*)
 
-            declare void @__quantum__qis__mz__body(%Qubit*, %Result*) #1
+            declare void @__quantum__qis__m__body(%Qubit*, %Result*) #1
 
             attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="2" "required_num_results"="2" }
             attributes #1 = { "irreversible" }
diff --git a/compiler/qsc/src/interpret/tests.rs b/compiler/qsc/src/interpret/tests.rs
index 77e5d020..2e07605d 100644
--- a/compiler/qsc/src/interpret/tests.rs
+++ b/compiler/qsc/src/interpret/tests.rs
@@ -725,7 +725,7 @@ mod given_interpreter {
                   call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
                   call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 0 to %Qubit*))
                   call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
-                  call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
+                  call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
                   call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
                   ret void
                 }
@@ -736,7 +736,7 @@ mod given_interpreter {
 
                 declare void @__quantum__rt__result_record_output(%Result*, i8*)
 
-                declare void @__quantum__qis__mz__body(%Qubit*, %Result*) #1
+                declare void @__quantum__qis__m__body(%Qubit*, %Result*) #1
 
                 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="2" "required_num_results"="1" }
                 attributes #1 = { "irreversible" }
@@ -960,7 +960,7 @@ mod given_interpreter {
                   call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
                   call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 0 to %Qubit*))
                   call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
-                  call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
+                  call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
                   call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
                   ret void
                 }
@@ -971,7 +971,7 @@ mod given_interpreter {
 
                 declare void @__quantum__rt__result_record_output(%Result*, i8*)
 
-                declare void @__quantum__qis__mz__body(%Qubit*, %Result*) #1
+                declare void @__quantum__qis__m__body(%Qubit*, %Result*) #1
 
                 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="2" "required_num_results"="1" }
                 attributes #1 = { "irreversible" }
@@ -1014,7 +1014,7 @@ mod given_interpreter {
                   call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
                   call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 0 to %Qubit*))
                   call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
-                  call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
+                  call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
                   call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
                   ret void
                 }
@@ -1025,7 +1025,7 @@ mod given_interpreter {
 
                 declare void @__quantum__rt__result_record_output(%Result*, i8*)
 
-                declare void @__quantum__qis__mz__body(%Qubit*, %Result*) #1
+                declare void @__quantum__qis__m__body(%Qubit*, %Result*) #1
 
                 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="2" "required_num_results"="1" }
                 attributes #1 = { "irreversible" }
@@ -1108,7 +1108,7 @@ mod given_interpreter {
                   call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
                   call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 0 to %Qubit*))
                   call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
-                  call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
+                  call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
                   call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
                   ret void
                 }
@@ -1119,7 +1119,7 @@ mod given_interpreter {
 
                 declare void @__quantum__rt__result_record_output(%Result*, i8*)
 
-                declare void @__quantum__qis__mz__body(%Qubit*, %Result*) #1
+                declare void @__quantum__qis__m__body(%Qubit*, %Result*) #1
 
                 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="2" "required_num_results"="1" }
                 attributes #1 = { "irreversible" }
@@ -1175,7 +1175,7 @@ mod given_interpreter {
                   call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
                   call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 0 to %Qubit*))
                   call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
-                  call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
+                  call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
                   call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
                   ret void
                 }
@@ -1186,7 +1186,7 @@ mod given_interpreter {
 
                 declare void @__quantum__rt__result_record_output(%Result*, i8*)
 
-                declare void @__quantum__qis__mz__body(%Qubit*, %Result*) #1
+                declare void @__quantum__qis__m__body(%Qubit*, %Result*) #1
 
                 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="2" "required_num_results"="1" }
                 attributes #1 = { "irreversible" }
@@ -1458,6 +1458,40 @@ mod given_interpreter {
             is_unit_with_output_eval_entry(&result, &output, "hello there...");
         }
 
+        #[test]
+        fn errors_returned_if_sources_do_not_match_profile() {
+            let source = indoc! { r#"
+            namespace A { operation Test() : Double { use q = Qubit(); mutable x = 1.0; if MResetZ(q) == One { set x = 2.0; } x } }"#};
+
+            let sources = SourceMap::new([("test".into(), source.into())], Some("A.Test()".into()));
+            let result = Interpreter::new(
+                true,
+                sources,
+                PackageType::Exe,
+                TargetCapabilityFlags::Adaptive
+                    | TargetCapabilityFlags::IntegerComputations
+                    | TargetCapabilityFlags::QubitReset,
+                LanguageFeatures::default(),
+            );
+
+            match result {
+                Ok(_) => panic!("Expected error, got interpreter."),
+                Err(errors) => is_error(
+                    &errors,
+                    &expect![[r#"
+                        cannot use a dynamic double value
+                           [<entry>] [A.Test()]
+                        cannot use a double value as an output
+                           [<entry>] [A.Test()]
+                        cannot use a dynamic double value
+                           [test] [set x = 2.0]
+                        cannot use a dynamic double value
+                           [test] [x]
+                    "#]],
+                ),
+            }
+        }
+
         #[test]
         fn stdlib_members_can_be_accessed_from_sources() {
             let source = indoc! { r#"
diff --git a/compiler/qsc_codegen/src/qir/tests.rs b/compiler/qsc_codegen/src/qir/tests.rs
index 80c8a0f5..dc0f67c5 100644
--- a/compiler/qsc_codegen/src/qir/tests.rs
+++ b/compiler/qsc_codegen/src/qir/tests.rs
@@ -29,8 +29,8 @@ fn single_qubit_rotation_decl_works() {
 
 #[test]
 fn measurement_decl_works() {
-    let decl = builder::mz_decl();
-    expect!["declare void @__quantum__qis__mz__body(%Qubit*, %Result*) #1"]
+    let decl = builder::m_decl();
+    expect!["declare void @__quantum__qis__m__body(%Qubit*, %Result*) #1"]
         .assert_eq(&decl.to_qir(&rir::Program::default()));
 }
 
@@ -135,7 +135,7 @@ fn bell_program() {
 
         declare void @__quantum__qis__cx__body(%Qubit*, %Qubit*)
 
-        declare void @__quantum__qis__mz__body(%Qubit*, %Result*) #1
+        declare void @__quantum__qis__m__body(%Qubit*, %Result*) #1
 
         declare void @__quantum__rt__array_record_output(i64, i8*)
 
@@ -145,8 +145,8 @@ fn bell_program() {
         block_0:
           call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 0 to %Qubit*))
           call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
-          call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
-          call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 1 to %Result*))
+          call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
+          call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 1 to %Result*))
           call void @__quantum__rt__array_record_output(i64 2, i8* null)
           call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
           call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 1 to %Result*), i8* null)
diff --git a/compiler/qsc_partial_eval/tests/calls.rs b/compiler/qsc_partial_eval/tests/calls.rs
index b38b30f0..515f6493 100644
--- a/compiler/qsc_partial_eval/tests/calls.rs
+++ b/compiler/qsc_partial_eval/tests/calls.rs
@@ -313,14 +313,14 @@ fn calls_to_unitary_that_conditionally_calls_intrinsic_with_dynamic_bool() {
         &program,
         measure_callable_id,
         &expect![[r#"
-        Callable:
-            name: __quantum__qis__mz__body
-            call_type: Measurement
-            input_type:
-                [0]: Qubit
-                [1]: Result
-            output_type: <VOID>
-            body: <NONE>"#]],
+            Callable:
+                name: __quantum__qis__m__body
+                call_type: Measurement
+                input_type:
+                    [0]: Qubit
+                    [1]: Result
+                output_type: <VOID>
+                body: <NONE>"#]],
     );
     let read_result_callable_id = CallableId(2);
     assert_callable(
@@ -457,14 +457,14 @@ fn call_to_operation_that_returns_measurement_result() {
         &program,
         measure_callable_id,
         &expect![[r#"
-        Callable:
-            name: __quantum__qis__mz__body
-            call_type: Measurement
-            input_type:
-                [0]: Qubit
-                [1]: Result
-            output_type: <VOID>
-            body: <NONE>"#]],
+            Callable:
+                name: __quantum__qis__m__body
+                call_type: Measurement
+                input_type:
+                    [0]: Qubit
+                    [1]: Result
+                output_type: <VOID>
+                body: <NONE>"#]],
     );
     let output_recording_callable_id = CallableId(2);
     assert_callable(
@@ -511,14 +511,14 @@ fn call_to_operation_that_returns_dynamic_bool() {
         &program,
         measure_callable_id,
         &expect![[r#"
-        Callable:
-            name: __quantum__qis__mz__body
-            call_type: Measurement
-            input_type:
-                [0]: Qubit
-                [1]: Result
-            output_type: <VOID>
-            body: <NONE>"#]],
+            Callable:
+                name: __quantum__qis__m__body
+                call_type: Measurement
+                input_type:
+                    [0]: Qubit
+                    [1]: Result
+                output_type: <VOID>
+                body: <NONE>"#]],
     );
     let read_result_callable_id = CallableId(2);
     assert_callable(
@@ -644,14 +644,14 @@ fn call_to_boolean_function_using_dynamic_result_as_argument_generates_branches(
         &program,
         measure_callable_id,
         &expect![[r#"
-        Callable:
-            name: __quantum__qis__mz__body
-            call_type: Measurement
-            input_type:
-                [0]: Qubit
-                [1]: Result
-            output_type: <VOID>
-            body: <NONE>"#]],
+            Callable:
+                name: __quantum__qis__m__body
+                call_type: Measurement
+                input_type:
+                    [0]: Qubit
+                    [1]: Result
+                output_type: <VOID>
+                body: <NONE>"#]],
     );
     let read_result_callable_id = CallableId(2);
     assert_callable(
diff --git a/compiler/qsc_partial_eval/tests/intrinsics.rs b/compiler/qsc_partial_eval/tests/intrinsics.rs
index b60cbcdb..158bfcb1 100644
--- a/compiler/qsc_partial_eval/tests/intrinsics.rs
+++ b/compiler/qsc_partial_eval/tests/intrinsics.rs
@@ -585,14 +585,14 @@ fn call_to_intrinsic_m_adds_callable_and_generates_instruction() {
         &program,
         op_callable_id,
         &expect![[r#"
-        Callable:
-            name: __quantum__qis__mz__body
-            call_type: Measurement
-            input_type:
-                [0]: Qubit
-                [1]: Result
-            output_type: <VOID>
-            body: <NONE>"#]],
+            Callable:
+                name: __quantum__qis__m__body
+                call_type: Measurement
+                input_type:
+                    [0]: Qubit
+                    [1]: Result
+                output_type: <VOID>
+                body: <NONE>"#]],
     );
     assert_block_instructions(
         &program,
@@ -712,14 +712,14 @@ fn call_to_intrinsic_begin_estimate_caching_with_dynamic_values_yields_true() {
         &program,
         measure_callable_id,
         &expect![[r#"
-        Callable:
-            name: __quantum__qis__mz__body
-            call_type: Measurement
-            input_type:
-                [0]: Qubit
-                [1]: Result
-            output_type: <VOID>
-            body: <NONE>"#]],
+            Callable:
+                name: __quantum__qis__m__body
+                call_type: Measurement
+                input_type:
+                    [0]: Qubit
+                    [1]: Result
+                output_type: <VOID>
+                body: <NONE>"#]],
     );
     let read_result_callable_id = CallableId(2);
     assert_callable(
diff --git a/compiler/qsc_partial_eval/tests/results.rs b/compiler/qsc_partial_eval/tests/results.rs
index 97110b2b..f2d82b95 100644
--- a/compiler/qsc_partial_eval/tests/results.rs
+++ b/compiler/qsc_partial_eval/tests/results.rs
@@ -83,14 +83,14 @@ fn result_ids_are_correct_for_measuring_one_qubit() {
         &program,
         op_callable_id,
         &expect![[r#"
-        Callable:
-            name: __quantum__qis__mz__body
-            call_type: Measurement
-            input_type:
-                [0]: Qubit
-                [1]: Result
-            output_type: <VOID>
-            body: <NONE>"#]],
+            Callable:
+                name: __quantum__qis__m__body
+                call_type: Measurement
+                input_type:
+                    [0]: Qubit
+                    [1]: Result
+                output_type: <VOID>
+                body: <NONE>"#]],
     );
     assert_callable(
         &program,
@@ -140,14 +140,14 @@ fn result_ids_are_correct_for_measuring_one_qubit_multiple_times() {
         &program,
         op_callable_id,
         &expect![[r#"
-        Callable:
-            name: __quantum__qis__mz__body
-            call_type: Measurement
-            input_type:
-                [0]: Qubit
-                [1]: Result
-            output_type: <VOID>
-            body: <NONE>"#]],
+            Callable:
+                name: __quantum__qis__m__body
+                call_type: Measurement
+                input_type:
+                    [0]: Qubit
+                    [1]: Result
+                output_type: <VOID>
+                body: <NONE>"#]],
     );
     assert_callable(
         &program,
@@ -213,14 +213,14 @@ fn result_ids_are_correct_for_measuring_one_qubit_multiple_times_into_array() {
         &program,
         op_callable_id,
         &expect![[r#"
-        Callable:
-            name: __quantum__qis__mz__body
-            call_type: Measurement
-            input_type:
-                [0]: Qubit
-                [1]: Result
-            output_type: <VOID>
-            body: <NONE>"#]],
+            Callable:
+                name: __quantum__qis__m__body
+                call_type: Measurement
+                input_type:
+                    [0]: Qubit
+                    [1]: Result
+                output_type: <VOID>
+                body: <NONE>"#]],
     );
     assert_callable(
         &program,
@@ -288,14 +288,14 @@ fn result_ids_are_correct_for_measuring_multiple_qubits() {
         &program,
         op_callable_id,
         &expect![[r#"
-        Callable:
-            name: __quantum__qis__mz__body
-            call_type: Measurement
-            input_type:
-                [0]: Qubit
-                [1]: Result
-            output_type: <VOID>
-            body: <NONE>"#]],
+            Callable:
+                name: __quantum__qis__m__body
+                call_type: Measurement
+                input_type:
+                    [0]: Qubit
+                    [1]: Result
+                output_type: <VOID>
+                body: <NONE>"#]],
     );
     assert_callable(
         &program,
diff --git a/compiler/qsc_rir/src/passes/defer_meas/tests.rs b/compiler/qsc_rir/src/passes/defer_meas/tests.rs
index 5390debe..c73cbd74 100644
--- a/compiler/qsc_rir/src/passes/defer_meas/tests.rs
+++ b/compiler/qsc_rir/src/passes/defer_meas/tests.rs
@@ -77,7 +77,7 @@ fn branching_block_measurements_deferred_properly() {
 }
 
 fn add_simple_measurement_block(program: &mut Program) {
-    program.callables.insert(CallableId(0), builder::mz_decl());
+    program.callables.insert(CallableId(0), builder::m_decl());
     program
         .callables
         .insert(CallableId(1), builder::mresetz_decl());
diff --git a/compiler/qsc_rir/src/passes/reindex_qubits/tests.rs b/compiler/qsc_rir/src/passes/reindex_qubits/tests.rs
index 5acbd6e2..50ea179a 100644
--- a/compiler/qsc_rir/src/passes/reindex_qubits/tests.rs
+++ b/compiler/qsc_rir/src/passes/reindex_qubits/tests.rs
@@ -6,7 +6,7 @@
 use expect_test::expect;
 
 use crate::{
-    builder::{cx_decl, h_decl, mresetz_decl, mz_decl, read_result_decl, reset_decl, x_decl},
+    builder::{cx_decl, h_decl, m_decl, mresetz_decl, read_result_decl, reset_decl, x_decl},
     rir::{
         Block, BlockId, CallableId, CallableType, Instruction, Literal, Operand, Program, Ty,
         Variable, VariableId,
@@ -63,17 +63,17 @@ fn qubit_reindexed_after_reset_removes_reset() {
 #[test]
 fn qubit_reindexed_after_mz() {
     const X: CallableId = CallableId(0);
-    const MZ: CallableId = CallableId(1);
+    const M: CallableId = CallableId(1);
     let mut program = Program::new();
     program.num_qubits = 1;
     program.callables.insert(X, x_decl());
-    program.callables.insert(MZ, mz_decl());
+    program.callables.insert(M, m_decl());
     program.blocks.insert(
         BlockId(0),
         Block(vec![
             Instruction::Call(X, vec![Operand::Literal(Literal::Qubit(0))], None),
             Instruction::Call(
-                MZ,
+                M,
                 vec![
                     Operand::Literal(Literal::Qubit(0)),
                     Operand::Literal(Literal::Result(0)),
@@ -82,7 +82,7 @@ fn qubit_reindexed_after_mz() {
             ),
             Instruction::Call(X, vec![Operand::Literal(Literal::Qubit(0))], None),
             Instruction::Call(
-                MZ,
+                M,
                 vec![
                     Operand::Literal(Literal::Qubit(0)),
                     Operand::Literal(Literal::Result(1)),
@@ -232,17 +232,17 @@ fn multiple_qubit_reindex() {
 #[test]
 fn qubit_reindexed_multiple_times_with_mz_inserts_multiple_cx() {
     const X: CallableId = CallableId(0);
-    const MZ: CallableId = CallableId(1);
+    const M: CallableId = CallableId(1);
     let mut program = Program::new();
     program.num_qubits = 1;
     program.callables.insert(X, x_decl());
-    program.callables.insert(MZ, mz_decl());
+    program.callables.insert(M, m_decl());
     program.blocks.insert(
         BlockId(0),
         Block(vec![
             Instruction::Call(X, vec![Operand::Literal(Literal::Qubit(0))], None),
             Instruction::Call(
-                MZ,
+                M,
                 vec![
                     Operand::Literal(Literal::Qubit(0)),
                     Operand::Literal(Literal::Result(0)),
@@ -251,7 +251,7 @@ fn qubit_reindexed_multiple_times_with_mz_inserts_multiple_cx() {
             ),
             Instruction::Call(X, vec![Operand::Literal(Literal::Qubit(0))], None),
             Instruction::Call(
-                MZ,
+                M,
                 vec![
                     Operand::Literal(Literal::Qubit(0)),
                     Operand::Literal(Literal::Result(1)),
@@ -260,7 +260,7 @@ fn qubit_reindexed_multiple_times_with_mz_inserts_multiple_cx() {
             ),
             Instruction::Call(X, vec![Operand::Literal(Literal::Qubit(0))], None),
             Instruction::Call(
-                MZ,
+                M,
                 vec![
                     Operand::Literal(Literal::Qubit(0)),
                     Operand::Literal(Literal::Result(2)),
@@ -269,7 +269,7 @@ fn qubit_reindexed_multiple_times_with_mz_inserts_multiple_cx() {
             ),
             Instruction::Call(X, vec![Operand::Literal(Literal::Qubit(0))], None),
             Instruction::Call(
-                MZ,
+                M,
                 vec![
                     Operand::Literal(Literal::Qubit(0)),
                     Operand::Literal(Literal::Result(3)),
@@ -318,13 +318,13 @@ fn qubit_reindexed_multiple_times_with_mz_inserts_multiple_cx() {
 #[test]
 fn qubit_reindexed_across_branches() {
     const X: CallableId = CallableId(0);
-    const MZ: CallableId = CallableId(1);
+    const M: CallableId = CallableId(1);
     const READ_RESULT: CallableId = CallableId(2);
     let mut program = Program::new();
     program.num_qubits = 1;
     program.num_results = 3;
     program.callables.insert(X, x_decl());
-    program.callables.insert(MZ, mz_decl());
+    program.callables.insert(M, m_decl());
     program.callables.insert(READ_RESULT, read_result_decl());
 
     program.blocks.insert(
@@ -332,7 +332,7 @@ fn qubit_reindexed_across_branches() {
         Block(vec![
             Instruction::Call(X, vec![Operand::Literal(Literal::Qubit(0))], None),
             Instruction::Call(
-                MZ,
+                M,
                 vec![
                     Operand::Literal(Literal::Qubit(0)),
                     Operand::Literal(Literal::Result(0)),
@@ -362,7 +362,7 @@ fn qubit_reindexed_across_branches() {
         Block(vec![
             Instruction::Call(X, vec![Operand::Literal(Literal::Qubit(0))], None),
             Instruction::Call(
-                MZ,
+                M,
                 vec![
                     Operand::Literal(Literal::Qubit(0)),
                     Operand::Literal(Literal::Result(1)),
@@ -376,7 +376,7 @@ fn qubit_reindexed_across_branches() {
         BlockId(2),
         Block(vec![
             Instruction::Call(
-                MZ,
+                M,
                 vec![
                     Operand::Literal(Literal::Qubit(0)),
                     Operand::Literal(Literal::Result(2)),
@@ -407,7 +407,7 @@ fn qubit_reindexed_across_branches() {
                     output_type: <VOID>
                     body: <NONE>
                 Callable 1: Callable:
-                    name: __quantum__qis__mz__body
+                    name: __quantum__qis__m__body
                     call_type: Measurement
                     input_type:
                         [0]: Qubit
@@ -457,7 +457,7 @@ fn qubit_reindexed_across_branches() {
                     output_type: <VOID>
                     body: <NONE>
                 Callable 1: Callable:
-                    name: __quantum__qis__mz__body
+                    name: __quantum__qis__m__body
                     call_type: Measurement
                     input_type:
                         [0]: Qubit
@@ -690,7 +690,7 @@ fn qubit_reindexed_across_branches_with_one_branch_longer() {
                     output_type: Boolean
                     body: <NONE>
                 Callable 3: Callable:
-                    name: __quantum__qis__mz__body
+                    name: __quantum__qis__m__body
                     call_type: Measurement
                     input_type:
                         [0]: Qubit
diff --git a/npm/qsharp/test/basics.js b/npm/qsharp/test/basics.js
index e84782d9..2d4c9618 100644
--- a/npm/qsharp/test/basics.js
+++ b/npm/qsharp/test/basics.js
@@ -786,6 +786,26 @@ test("debug service loading source with bad entry expr fails - web worker", asyn
   }
 });
 
+test("debug service loading source that doesn't match profile fails - web worker", async () => {
+  const debugService = getDebugServiceWorker();
+  try {
+    const result = await debugService.loadSource(
+      [
+        [
+          "test.qs",
+          `namespace A { operation Test() : Double { use q = Qubit(); mutable x = 1.0; if MResetZ(q) == One { set x = 2.0; } x } }`,
+        ],
+      ],
+      "adaptive_ri",
+      "A.Test()",
+      [],
+    );
+    assert.ok(typeof result === "string" && result.trim().length > 0);
+  } finally {
+    debugService.terminate();
+  }
+});
+
 test("debug service loading source with good entry expr succeeds - web worker", async () => {
   const debugService = getDebugServiceWorker();
   try {
diff --git a/pip/tests-qir/test_qir.py b/pip/tests-qir/test_qir.py
index fec73b08..32626bf2 100644
--- a/pip/tests-qir/test_qir.py
+++ b/pip/tests-qir/test_qir.py
@@ -105,8 +105,8 @@ def test_compile_qir_all_gates() -> None:
     check_call(19, "__quantum__qis__h__body", 1)
     check_call(20, "__quantum__qis__cz__body", 2)
     check_call(21, "__quantum__qis__h__body", 1)
-    check_call(22, "__quantum__qis__mz__body", 2)
-    check_call(23, "__quantum__qis__mz__body", 2)
+    check_call(22, "__quantum__qis__m__body", 2)
+    check_call(23, "__quantum__qis__m__body", 2)
     check_call(24, "__quantum__rt__tuple_record_output", 2)
     check_call(25, "__quantum__rt__result_record_output", 2)
     check_call(26, "__quantum__rt__result_record_output", 2)
diff --git a/pip/tests/test_interpreter.py b/pip/tests/test_interpreter.py
index 464c8fdc..4d4cc287 100644
--- a/pip/tests/test_interpreter.py
+++ b/pip/tests/test_interpreter.py
@@ -426,7 +426,7 @@ def test_base_qir_can_be_generated() -> None:
           call void @__quantum__qis__rz__body(double 2.0, %Qubit* inttoptr (i64 0 to %Qubit*))
           call void @__quantum__qis__rz__body(double 0.0, %Qubit* inttoptr (i64 0 to %Qubit*))
           call void @__quantum__qis__rz__body(double 1.0, %Qubit* inttoptr (i64 0 to %Qubit*))
-          call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
+          call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*))
           call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
           ret void
         }
@@ -435,7 +435,7 @@ def test_base_qir_can_be_generated() -> None:
 
         declare void @__quantum__rt__result_record_output(%Result*, i8*)
 
-        declare void @__quantum__qis__mz__body(%Qubit*, %Result*) #1
+        declare void @__quantum__qis__m__body(%Qubit*, %Result*) #1
 
         attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="1" "required_num_results"="1" }
         attributes #1 = { "irreversible" }