Repository: microsoft/qsharp
Pull request #2107 (2025-01-17 19:25:44)

Update rust to v1.84.0
This PR updates the Rust version to 1.84.0.

To fix some new clippy lints I had to upgrade `PyO3` to its latest version, this led to `PyO3` related changes.
For the same reason I had to update `wasm_bindgen` to its latest version, but no further changes were required.


Patch:
diff --git a/.ado/publish.yml b/.ado/publish.yml
index 440052ab..2b27ab74 100644
--- a/.ado/publish.yml
+++ b/.ado/publish.yml
@@ -19,7 +19,7 @@ schedules:
 
 variables:
   CARGO_TERM_COLOR: always
-  RUST_TOOLCHAIN_VERSION: "1.82"
+  RUST_TOOLCHAIN_VERSION: "1.84"
 
 resources:
   repositories:
diff --git a/.github/workflows/bench-reports.yml b/.github/workflows/bench-reports.yml
index 7a01bad5..a17ba41d 100644
--- a/.github/workflows/bench-reports.yml
+++ b/.github/workflows/bench-reports.yml
@@ -8,7 +8,7 @@ env:
   CARGO_TERM_COLOR: always
   NODE_VERSION: "18.17.1"
   PYTHON_VERSION: "3.11"
-  RUST_TOOLCHAIN_VERSION: "1.82"
+  RUST_TOOLCHAIN_VERSION: "1.84"
 
 jobs:
   runBenchmark:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index fb1ea8fc..96d46b81 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -20,7 +20,7 @@ env:
   CARGO_TERM_COLOR: always
   NODE_VERSION: "18.17.1"
   PYTHON_VERSION: "3.11"
-  RUST_TOOLCHAIN_VERSION: "1.82"
+  RUST_TOOLCHAIN_VERSION: "1.84"
   RUST_TOOLCHAIN_COMPONENTS: rustfmt clippy
 
 jobs:
diff --git a/.github/workflows/memory_profile.yml b/.github/workflows/memory_profile.yml
index b4d20707..ede4974a 100644
--- a/.github/workflows/memory_profile.yml
+++ b/.github/workflows/memory_profile.yml
@@ -15,7 +15,7 @@ env:
   CARGO_TERM_COLOR: always
   NODE_VERSION: "18.17.1"
   PYTHON_VERSION: "3.11"
-  RUST_TOOLCHAIN_VERSION: "1.82"
+  RUST_TOOLCHAIN_VERSION: "1.84"
   RUST_TOOLCHAIN_COMPONENTS: rustfmt clippy
 
 jobs:
diff --git a/.github/workflows/publish-playground.yml b/.github/workflows/publish-playground.yml
index b6cab1b8..fe218fc3 100644
--- a/.github/workflows/publish-playground.yml
+++ b/.github/workflows/publish-playground.yml
@@ -11,7 +11,7 @@ on:
 
 env:
   CARGO_TERM_COLOR: always
-  RUST_TOOLCHAIN_VERSION: "1.82"
+  RUST_TOOLCHAIN_VERSION: "1.84"
   RUST_TOOLCHAIN_COMPONENTS: rustfmt clippy
 
 # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
diff --git a/Cargo.lock b/Cargo.lock
index 8f495d01..c18c8529 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,6 +1,6 @@
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
-version = 3
+version = 4
 
 [[package]]
 name = "addr2line"
@@ -133,7 +133,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.76",
+ "syn 2.0.87",
 ]
 
 [[package]]
@@ -288,7 +288,7 @@ dependencies = [
  "heck",
  "proc-macro2",
  "quote",
- "syn 2.0.76",
+ "syn 2.0.87",
 ]
 
 [[package]]
@@ -416,7 +416,7 @@ checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.76",
+ "syn 2.0.87",
 ]
 
 [[package]]
@@ -530,7 +530,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.76",
+ "syn 2.0.87",
 ]
 
 [[package]]
@@ -817,7 +817,7 @@ checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.76",
+ "syn 2.0.87",
 ]
 
 [[package]]
@@ -860,7 +860,7 @@ checksum = "254a5372af8fc138e36684761d3c0cdb758a4410e938babcff1c860ce14ddbfc"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.76",
+ "syn 2.0.87",
 ]
 
 [[package]]
@@ -1105,9 +1105,9 @@ dependencies = [
 
 [[package]]
 name = "pyo3"
-version = "0.22.4"
+version = "0.23.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00e89ce2565d6044ca31a3eb79a334c3a79a841120a98f64eea9f579564cb691"
+checksum = "57fe09249128b3173d092de9523eaa75136bf7ba85e0d69eca241c7939c933cc"
 dependencies = [
  "cfg-if",
  "indoc",
@@ -1125,9 +1125,9 @@ dependencies = [
 
 [[package]]
 name = "pyo3-build-config"
-version = "0.22.4"
+version = "0.23.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8afbaf3abd7325e08f35ffb8deb5892046fcb2608b703db6a583a5ba4cea01e"
+checksum = "1cd3927b5a78757a0d71aa9dff669f903b1eb64b54142a9bd9f757f8fde65fd7"
 dependencies = [
  "once_cell",
  "python3-dll-a",
@@ -1136,9 +1136,9 @@ dependencies = [
 
 [[package]]
 name = "pyo3-ffi"
-version = "0.22.4"
+version = "0.23.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec15a5ba277339d04763f4c23d85987a5b08cbb494860be141e6a10a8eb88022"
+checksum = "dab6bb2102bd8f991e7749f130a70d05dd557613e39ed2deeee8e9ca0c4d548d"
 dependencies = [
  "libc",
  "pyo3-build-config",
@@ -1146,34 +1146,34 @@ dependencies = [
 
 [[package]]
 name = "pyo3-macros"
-version = "0.22.4"
+version = "0.23.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "15e0f01b5364bcfbb686a52fc4181d412b708a68ed20c330db9fc8d2c2bf5a43"
+checksum = "91871864b353fd5ffcb3f91f2f703a22a9797c91b9ab497b1acac7b07ae509c7"
 dependencies = [
  "proc-macro2",
  "pyo3-macros-backend",
  "quote",
- "syn 2.0.76",
+ "syn 2.0.87",
 ]
 
 [[package]]
 name = "pyo3-macros-backend"
-version = "0.22.4"
+version = "0.23.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a09b550200e1e5ed9176976d0060cbc2ea82dc8515da07885e7b8153a85caacb"
+checksum = "43abc3b80bc20f3facd86cd3c60beed58c3e2aa26213f3cda368de39c60a27e4"
 dependencies = [
  "heck",
  "proc-macro2",
  "pyo3-build-config",
  "quote",
- "syn 2.0.76",
+ "syn 2.0.87",
 ]
 
 [[package]]
 name = "python3-dll-a"
-version = "0.2.10"
+version = "0.2.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd0b78171a90d808b319acfad166c4790d9e9759bbc14ac8273fe133673dd41b"
+checksum = "9b66f9171950e674e64bad3456e11bb3cca108e5c34844383cfe277f45c8a7a8"
 dependencies = [
  "cc",
 ]
@@ -1788,9 +1788,9 @@ dependencies = [
 
 [[package]]
 name = "serde"
-version = "1.0.209"
+version = "1.0.217"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09"
+checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
 dependencies = [
  "serde_derive",
 ]
@@ -1808,13 +1808,13 @@ dependencies = [
 
 [[package]]
 name = "serde_derive"
-version = "1.0.209"
+version = "1.0.217"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170"
+checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.76",
+ "syn 2.0.87",
 ]
 
 [[package]]
@@ -1921,9 +1921,9 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "2.0.76"
+version = "2.0.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525"
+checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1980,7 +1980,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.76",
+ "syn 2.0.87",
 ]
 
 [[package]]
@@ -2012,7 +2012,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.76",
+ "syn 2.0.87",
 ]
 
 [[package]]
@@ -2093,27 +2093,27 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
 
 [[package]]
 name = "wasm-bindgen"
-version = "0.2.93"
+version = "0.2.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5"
+checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
 dependencies = [
  "cfg-if",
  "once_cell",
+ "rustversion",
  "wasm-bindgen-macro",
 ]
 
 [[package]]
 name = "wasm-bindgen-backend"
-version = "0.2.93"
+version = "0.2.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b"
+checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
 dependencies = [
  "bumpalo",
  "log",
- "once_cell",
  "proc-macro2",
  "quote",
- "syn 2.0.76",
+ "syn 2.0.87",
  "wasm-bindgen-shared",
 ]
 
@@ -2131,9 +2131,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro"
-version = "0.2.93"
+version = "0.2.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf"
+checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
 dependencies = [
  "quote",
  "wasm-bindgen-macro-support",
@@ -2141,22 +2141,25 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro-support"
-version = "0.2.93"
+version = "0.2.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836"
+checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.76",
+ "syn 2.0.87",
  "wasm-bindgen-backend",
  "wasm-bindgen-shared",
 ]
 
 [[package]]
 name = "wasm-bindgen-shared"
-version = "0.2.93"
+version = "0.2.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484"
+checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
+dependencies = [
+ "unicode-ident",
+]
 
 [[package]]
 name = "web-sys"
@@ -2440,5 +2443,5 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.76",
+ "syn 2.0.87",
 ]
diff --git a/Cargo.toml b/Cargo.toml
index 12235954..6c927a5e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -73,11 +73,11 @@ regex-lite = "0.1"
 rustc-hash = "1"
 serde = { version = "1.0", features = [ "derive" ] }
 serde-wasm-bindgen = "0.6"
-wasm-bindgen = "0.2"
+wasm-bindgen = "0.2.100"
 wasm-bindgen-futures = "0.4"
 rand = "0.8"
 serde_json = "1.0"
-pyo3 = "0.22"
+pyo3 = "0.23.4"
 quantum-sparse-sim = { git = "https://github.com/qir-alliance/qir-runner", rev = "562e2c11ad685dd01bfc1ae975e00d4133615995" }
 async-trait = "0.1"
 tokio = { version = "1.35", features = ["macros", "rt"] }
diff --git a/compiler/qsc/src/error.rs b/compiler/qsc/src/error.rs
index 89e27dad..18f835f1 100644
--- a/compiler/qsc/src/error.rs
+++ b/compiler/qsc/src/error.rs
@@ -19,8 +19,8 @@ impl<E> WithStack<E> {
         WithStack { error, stack_trace }
     }
 
-    pub(super) fn stack_trace(&self) -> &Option<String> {
-        &self.stack_trace
+    pub(super) fn stack_trace(&self) -> Option<&String> {
+        self.stack_trace.as_ref()
     }
 
     pub fn error(&self) -> &E {
diff --git a/compiler/qsc/src/interpret.rs b/compiler/qsc/src/interpret.rs
index 2c736ee7..0f7c75d9 100644
--- a/compiler/qsc/src/interpret.rs
+++ b/compiler/qsc/src/interpret.rs
@@ -71,10 +71,10 @@ use thiserror::Error;
 
 impl Error {
     #[must_use]
-    pub fn stack_trace(&self) -> &Option<String> {
+    pub fn stack_trace(&self) -> Option<&String> {
         match &self {
             Error::Eval(err) => err.stack_trace(),
-            _ => &None,
+            _ => None,
         }
     }
 }
diff --git a/compiler/qsc_ast/src/ast.rs b/compiler/qsc_ast/src/ast.rs
index 21b3fff2..f69e11a4 100644
--- a/compiler/qsc_ast/src/ast.rs
+++ b/compiler/qsc_ast/src/ast.rs
@@ -937,17 +937,23 @@ impl Display for ExprKind {
             ExprKind::Field(expr, id) => display_field(indent, expr, id)?,
             ExprKind::For(iter, iterable, body) => display_for(indent, iter, iterable, body)?,
             ExprKind::Hole => write!(indent, "Hole")?,
-            ExprKind::If(cond, body, els) => display_if(indent, cond, body, els)?,
+            ExprKind::If(cond, body, els) => display_if(indent, cond, body, els.as_deref())?,
             ExprKind::Index(array, index) => display_index(indent, array, index)?,
             ExprKind::Interpolate(components) => display_interpolate(indent, components)?,
             ExprKind::Lambda(kind, param, expr) => display_lambda(indent, *kind, param, expr)?,
             ExprKind::Lit(lit) => write!(indent, "Lit: {lit}")?,
             ExprKind::Paren(e) => write!(indent, "Paren: {e}")?,
             ExprKind::Path(p) => write!(indent, "Path: {p}")?,
-            ExprKind::Range(start, step, end) => display_range(indent, start, step, end)?,
-            ExprKind::Repeat(repeat, until, fixup) => display_repeat(indent, repeat, until, fixup)?,
+            ExprKind::Range(start, step, end) => {
+                display_range(indent, start.as_deref(), step.as_deref(), end.as_deref())?;
+            }
+            ExprKind::Repeat(repeat, until, fixup) => {
+                display_repeat(indent, repeat, until, fixup.as_deref())?;
+            }
             ExprKind::Return(e) => write!(indent, "Return: {e}")?,
-            ExprKind::Struct(name, copy, fields) => display_struct(indent, name, copy, fields)?,
+            ExprKind::Struct(name, copy, fields) => {
+                display_struct(indent, name, copy.as_deref(), fields)?;
+            }
             ExprKind::TernOp(op, expr1, expr2, expr3) => {
                 display_tern_op(indent, *op, expr1, expr2, expr3)?;
             }
@@ -1073,7 +1079,7 @@ fn display_if(
     mut indent: Indented<Formatter>,
     cond: &Expr,
     body: &Block,
-    els: &Option<Box<Expr>>,
+    els: Option<&Expr>,
 ) -> fmt::Result {
     write!(indent, "If:")?;
     indent = set_indentation(indent, 1);
@@ -1124,9 +1130,9 @@ fn display_lambda(
 
 fn display_range(
     mut indent: Indented<Formatter>,
-    start: &Option<Box<Expr>>,
-    step: &Option<Box<Expr>>,
-    end: &Option<Box<Expr>>,
+    start: Option<&Expr>,
+    step: Option<&Expr>,
+    end: Option<&Expr>,
 ) -> fmt::Result {
     write!(indent, "Range:")?;
     indent = set_indentation(indent, 1);
@@ -1149,7 +1155,7 @@ fn display_repeat(
     mut indent: Indented<Formatter>,
     repeat: &Block,
     until: &Expr,
-    fixup: &Option<Box<Block>>,
+    fixup: Option<&Block>,
 ) -> fmt::Result {
     write!(indent, "Repeat:")?;
     indent = set_indentation(indent, 1);
@@ -1165,7 +1171,7 @@ fn display_repeat(
 fn display_struct(
     mut indent: Indented<Formatter>,
     name: &PathKind,
-    copy: &Option<Box<Expr>>,
+    copy: Option<&Expr>,
     fields: &[Box<FieldAssign>],
 ) -> fmt::Result {
     write!(indent, "Struct ({name}):")?;
@@ -1612,7 +1618,7 @@ impl Idents for &[Ident] {
     }
 }
 
-impl<T, U> Idents for (&T, &U)
+impl<T, U> Idents for (T, U)
 where
     T: Idents,
     U: Idents,
@@ -1628,6 +1634,12 @@ impl Idents for Ident {
     }
 }
 
+impl Idents for &Ident {
+    fn iter(&self) -> impl Iterator<Item = &Ident> {
+        once(*self)
+    }
+}
+
 impl Idents for Path {
     fn iter(&self) -> impl Iterator<Item = &Ident> {
         self.segments
diff --git a/compiler/qsc_data_structures/src/index_map.rs b/compiler/qsc_data_structures/src/index_map.rs
index d5da735d..67f58f50 100644
--- a/compiler/qsc_data_structures/src/index_map.rs
+++ b/compiler/qsc_data_structures/src/index_map.rs
@@ -114,7 +114,7 @@ impl<K: Into<usize>, V> IndexMap<K, V> {
 
     pub fn contains_key(&self, key: K) -> bool {
         let index: usize = key.into();
-        self.values.get(index).map_or(false, Option::is_some)
+        self.values.get(index).is_some_and(Option::is_some)
     }
 
     pub fn get(&self, key: K) -> Option<&V> {
diff --git a/compiler/qsc_doc_gen/src/display.rs b/compiler/qsc_doc_gen/src/display.rs
index c63ebe6c..d0d2ac2c 100644
--- a/compiler/qsc_doc_gen/src/display.rs
+++ b/compiler/qsc_doc_gen/src/display.rs
@@ -124,7 +124,7 @@ struct IdentTy<'a> {
     ty: &'a ast::Ty,
 }
 
-impl<'a> Display for IdentTy<'a> {
+impl Display for IdentTy<'_> {
     fn fmt(&self, f: &mut Formatter<'_>) -> Result {
         write!(f, "{} : {}", self.ident.name, AstTy { ty: self.ty },)
     }
@@ -136,7 +136,7 @@ struct NameTyId<'a> {
     ty_id: ast::NodeId,
 }
 
-impl<'a> Display for NameTyId<'a> {
+impl Display for NameTyId<'_> {
     fn fmt(&self, f: &mut Formatter<'_>) -> Result {
         write!(
             f,
@@ -202,7 +202,7 @@ struct AstCallableDecl<'a> {
     decl: &'a ast::CallableDecl,
 }
 
-impl<'a> Display for AstCallableDecl<'a> {
+impl Display for AstCallableDecl<'_> {
     fn fmt(&self, f: &mut Formatter<'_>) -> Result {
         let kind = match self.decl.kind {
             ast::CallableKind::Function => "function",
@@ -285,7 +285,7 @@ struct HirPat<'a> {
     pat: &'a hir::Pat,
 }
 
-impl<'a> Display for HirPat<'a> {
+impl Display for HirPat<'_> {
     fn fmt(&self, f: &mut Formatter<'_>) -> Result {
         match &self.pat.kind {
             hir::PatKind::Bind(name) => write!(f, "{} : {}", name.name, self.pat.ty.display()),
@@ -312,7 +312,7 @@ struct AstPat<'a> {
     pat: &'a ast::Pat,
 }
 
-impl<'a> Display for AstPat<'a> {
+impl Display for AstPat<'_> {
     fn fmt(&self, f: &mut Formatter<'_>) -> Result {
         match &*self.pat.kind {
             ast::PatKind::Bind(ident, anno) => match anno {
@@ -430,7 +430,7 @@ impl<'a> HirUdt<'a> {
     }
 }
 
-impl<'a> Display for HirUdt<'a> {
+impl Display for HirUdt<'_> {
     fn fmt(&self, f: &mut Formatter<'_>) -> Result {
         if self.is_struct {
             match &self.udt.definition.kind {
@@ -520,7 +520,7 @@ struct TyId<'a> {
     ty_id: ast::NodeId,
 }
 
-impl<'a> Display for TyId<'a> {
+impl Display for TyId<'_> {
     fn fmt(&self, f: &mut Formatter<'_>) -> Result {
         if let Some(ty) = self.lookup.get_ty(self.ty_id) {
             write!(f, "{}", ty.display())
@@ -534,7 +534,7 @@ struct AstTy<'a> {
     ty: &'a ast::Ty,
 }
 
-impl<'a> Display for AstTy<'a> {
+impl Display for AstTy<'_> {
     fn fmt(&self, f: &mut Formatter<'_>) -> Result {
         match self.ty.kind.as_ref() {
             ast::TyKind::Array(ty) => write!(f, "{}[]", AstTy { ty }),
@@ -566,7 +566,7 @@ struct FunctorExpr<'a> {
     functors: &'a Option<Box<ast::FunctorExpr>>,
 }
 
-impl<'a> Display for FunctorExpr<'a> {
+impl Display for FunctorExpr<'_> {
     fn fmt(&self, f: &mut Formatter<'_>) -> Result {
         match self.functors {
             Some(functors) => {
@@ -582,7 +582,7 @@ struct AstPathKind<'a> {
     path: &'a ast::PathKind,
 }
 
-impl<'a> Display for AstPathKind<'a> {
+impl Display for AstPathKind<'_> {
     fn fmt(&self, f: &mut Formatter<'_>) -> Result {
         if let ast::PathKind::Ok(path) = self.path {
             write!(f, "{}", path.full_name())
@@ -596,7 +596,7 @@ struct TyDef<'a> {
     def: &'a ast::TyDef,
 }
 
-impl<'a> Display for TyDef<'a> {
+impl Display for TyDef<'_> {
     fn fmt(&self, f: &mut Formatter<'_>) -> Result {
         match self.def.kind.as_ref() {
             ast::TyDefKind::Field(name, ty) => match name {
diff --git a/compiler/qsc_eval/src/output.rs b/compiler/qsc_eval/src/output.rs
index 342b96ff..fe424249 100644
--- a/compiler/qsc_eval/src/output.rs
+++ b/compiler/qsc_eval/src/output.rs
@@ -37,7 +37,7 @@ impl<'a> GenericReceiver<'a> {
     }
 }
 
-impl<'a> Receiver for GenericReceiver<'a> {
+impl Receiver for GenericReceiver<'_> {
     fn state(&mut self, state: Vec<(BigUint, Complex64)>, qubit_count: usize) -> Result<(), Error> {
         writeln!(self.writer, "STATE:").map_err(|_| Error)?;
         if qubit_count > 0 {
@@ -89,7 +89,7 @@ impl<'a> CursorReceiver<'a> {
     }
 }
 
-impl<'a> Receiver for CursorReceiver<'a> {
+impl Receiver for CursorReceiver<'_> {
     fn state(&mut self, state: Vec<(BigUint, Complex64)>, qubit_count: usize) -> Result<(), Error> {
         writeln!(self.cursor, "STATE:").map_err(|_| Error)?;
         if qubit_count > 0 {
diff --git a/compiler/qsc_fir/src/global.rs b/compiler/qsc_fir/src/global.rs
index 30fc4b9b..36770b7c 100644
--- a/compiler/qsc_fir/src/global.rs
+++ b/compiler/qsc_fir/src/global.rs
@@ -136,7 +136,7 @@ impl PackageIter<'_> {
     }
 }
 
-impl<'a> Iterator for PackageIter<'a> {
+impl Iterator for PackageIter<'_> {
     type Item = Global;
 
     fn next(&mut self) -> Option<Self::Item> {
diff --git a/compiler/qsc_formatter/src/formatter.rs b/compiler/qsc_formatter/src/formatter.rs
index c3e4022a..87dd15e9 100644
--- a/compiler/qsc_formatter/src/formatter.rs
+++ b/compiler/qsc_formatter/src/formatter.rs
@@ -227,7 +227,7 @@ struct Formatter<'a> {
     import_export_state: ImportExportState,
 }
 
-impl<'a> Formatter<'a> {
+impl Formatter<'_> {
     fn apply_rules(
         &mut self,
         left: &ConcreteToken,
diff --git a/compiler/qsc_frontend/src/compile.rs b/compiler/qsc_frontend/src/compile.rs
index bd73f608..595bc55b 100644
--- a/compiler/qsc_frontend/src/compile.rs
+++ b/compiler/qsc_frontend/src/compile.rs
@@ -543,8 +543,7 @@ fn resolve_all(
     let mut globals = resolve::GlobalTable::new();
     let mut errors = Vec::new();
     if let Some(unit) = store.get(PackageId::CORE) {
-        if let Err(errs) =
-            globals.add_external_package(PackageId::CORE, &unit.package, store, &None)
+        if let Err(errs) = globals.add_external_package(PackageId::CORE, &unit.package, store, None)
         {
             errors.extend(errs);
         }
@@ -555,7 +554,8 @@ fn resolve_all(
         let unit = store
             .get(*id)
             .expect("dependency should be in package store before compilation");
-        if let Err(errs) = globals.add_external_package(*id, &unit.package, store, alias) {
+        if let Err(errs) = globals.add_external_package(*id, &unit.package, store, alias.as_deref())
+        {
             errors.extend(errs);
         };
         dropped_names.extend(unit.dropped_names.iter().cloned());
diff --git a/compiler/qsc_frontend/src/incremental.rs b/compiler/qsc_frontend/src/incremental.rs
index 7bcaff9a..0a33b345 100644
--- a/compiler/qsc_frontend/src/incremental.rs
+++ b/compiler/qsc_frontend/src/incremental.rs
@@ -71,7 +71,7 @@ impl Compiler {
         let mut dropped_names = Vec::new();
         if let Some(unit) = store.get(PackageId::CORE) {
             resolve_globals
-                .add_external_package(PackageId::CORE, &unit.package, store, &None)
+                .add_external_package(PackageId::CORE, &unit.package, store, None)
                 .expect("CORE is added before all other packages and can not clobber anything");
             typeck_globals.add_external_package(PackageId::CORE, &unit.package, store);
             dropped_names.extend(unit.dropped_names.iter().cloned());
@@ -83,7 +83,7 @@ impl Compiler {
                 .get(*id)
                 .expect("dependency should be added to package store before compilation");
             if let Err(mut errs) =
-                resolve_globals.add_external_package(*id, &unit.package, store, alias)
+                resolve_globals.add_external_package(*id, &unit.package, store, alias.as_deref())
             {
                 errors.append(&mut errs);
             };
diff --git a/compiler/qsc_frontend/src/lower.rs b/compiler/qsc_frontend/src/lower.rs
index c349b203..fb56d42d 100644
--- a/compiler/qsc_frontend/src/lower.rs
+++ b/compiler/qsc_frontend/src/lower.rs
@@ -142,7 +142,7 @@ impl Lowerer {
         assigner: &'a mut Assigner,
         names: &'a Names,
         tys: &'a typeck::Table,
-    ) -> With {
+    ) -> With<'a> {
         With {
             lowerer: self,
             assigner,
diff --git a/compiler/qsc_frontend/src/resolve.rs b/compiler/qsc_frontend/src/resolve.rs
index 2843be41..f02f1113 100644
--- a/compiler/qsc_frontend/src/resolve.rs
+++ b/compiler/qsc_frontend/src/resolve.rs
@@ -26,7 +26,7 @@ use qsc_hir::{
     ty::{ParamId, Prim},
 };
 use rustc_hash::{FxHashMap, FxHashSet};
-use std::{cmp::Ordering, sync::Arc};
+use std::cmp::Ordering;
 use std::{collections::hash_map::Entry, rc::Rc, str::FromStr, vec};
 use thiserror::Error;
 
@@ -276,7 +276,10 @@ pub struct Locals {
 }
 
 impl Locals {
-    fn get_scopes<'a>(&'a self, scope_chain: &'a [ScopeId]) -> impl Iterator<Item = &Scope> + 'a {
+    fn get_scopes<'a>(
+        &'a self,
+        scope_chain: &'a [ScopeId],
+    ) -> impl Iterator<Item = &'a Scope> + 'a {
         // reverse to go from innermost -> outermost
         scope_chain.iter().rev().map(|id| {
             self.scopes
@@ -503,7 +506,7 @@ impl AstVisitor<'_> for ExportImportVisitor<'_> {
             // the below line ensures that this namespace opens itself, in case
             // we are re-opening a namespace. This is important, as without this,
             // a re-opened namespace would only have knowledge of its scopes.
-            visitor.resolver.bind_open(&namespace.name, &None, root_id);
+            visitor.resolver.bind_open(&namespace.name, None, root_id);
             for item in &namespace.items {
                 match &*item.kind {
                     ItemKind::ImportOrExport(decl) => {
@@ -525,7 +528,9 @@ impl AstVisitor<'_> for ExportImportVisitor<'_> {
                         // namespace A { callable foo() { open B; export { SomethingFromB }; } }
                         //                                        ^^^^^^ export from non-namespace scope is not allowed
                         // ```
-                        visitor.resolver.bind_open(path.as_ref(), alias, ns);
+                        visitor
+                            .resolver
+                            .bind_open(path.as_ref(), alias.as_deref(), ns);
                     }
                     _ => ast_visit::walk_item(visitor, item),
                 }
@@ -644,7 +649,7 @@ impl Resolver {
             &self.globals,
             self.locals.get_scopes(&self.curr_scope_chain),
             name,
-            &None,
+            None,
         ) {
             Ok(res) => {
                 self.check_item_status(&res, name.name.to_string(), name.span);
@@ -670,7 +675,7 @@ impl Resolver {
                         &self.globals,
                         self.locals.get_scopes(&self.curr_scope_chain),
                         first,
-                        &None,
+                        None,
                     ) {
                         Ok(res) if matches!(res, Res::Local(_)) => {
                             // The path is a field accessor.
@@ -701,7 +706,7 @@ impl Resolver {
                 &self.globals,
                 self.locals.get_scopes(&self.curr_scope_chain),
                 first,
-                &None,
+                None,
             ) {
                 Ok(res) if matches!(res, Res::Local(_)) => {
                     // The path is a field accessor.
@@ -721,7 +726,7 @@ impl Resolver {
             &self.globals,
             self.locals.get_scopes(&self.curr_scope_chain),
             name,
-            segments,
+            segments.as_deref(),
         ) {
             Ok(res) => {
                 self.check_item_status(&res, path.name.name.to_string(), path.span);
@@ -788,7 +793,7 @@ impl Resolver {
     fn bind_open(
         &mut self,
         name: &impl Idents,
-        alias: &Option<Box<Ident>>,
+        alias: Option<&Ident>,
         current_namespace: NamespaceId,
     ) {
         let (_current_ns_name, current_namespace) = self
@@ -838,7 +843,7 @@ impl Resolver {
                 if let PathKind::Ok(path) = name {
                     self.bind_open(
                         path.as_ref(),
-                        alias,
+                        alias.as_deref(),
                         namespace.unwrap_or_else(|| self.globals.namespaces.root_id()),
                     );
                 }
@@ -1163,7 +1168,7 @@ impl Resolver {
             return;
         };
         if !is_export {
-            self.bind_open(path.as_ref(), &None, ns);
+            self.bind_open(path.as_ref(), None, ns);
         }
     }
 
@@ -1238,7 +1243,7 @@ impl Resolver {
                     .insert_with_id(current_namespace, ns, &alias.name)?;
             } else {
                 // for imports, we just bind the namespace as an open
-                self.bind_open(path.as_ref(), &alias, ns);
+                self.bind_open(path.as_ref(), alias.as_deref(), ns);
             }
         } else {
             self.errors.push(err.clone());
@@ -1356,7 +1361,8 @@ impl AstVisitor<'_> for With<'_> {
                     .unwrap_or_else(|| self.resolver.globals.namespaces.root_id());
                 // Only locally scoped opens are handled here.
                 // There is only a namespace parent scope if we aren't executing incremental fragments.
-                self.resolver.bind_open(path.as_ref(), alias, namespace);
+                self.resolver
+                    .bind_open(path.as_ref(), alias.as_deref(), namespace);
             }
             _ => ast_visit::walk_item(self, item),
         }
@@ -1576,13 +1582,11 @@ impl GlobalTable {
         id: PackageId,
         package: &hir::Package,
         store: &crate::compile::PackageStore,
-        alias: &Option<Arc<str>>,
+        alias: Option<&str>,
     ) -> Result<(), Vec<Error>> {
         // if there is a package-level alias defined, use that for the root namespace.
         let root = match alias {
-            Some(alias) => self
-                .scope
-                .insert_or_find_namespace(vec![Rc::from(&**alias)]),
+            Some(alias) => self.scope.insert_or_find_namespace(vec![Rc::from(alias)]),
             // otherwise, these namespaces will be inserted into the root of the local package
             // without any alias.
             None => self.scope.namespaces.root_id(),
@@ -1761,7 +1765,7 @@ fn is_field_update<'a>(
             {
                 let name = &path.name;
                 let namespace = &path.segments;
-                resolve(NameKind::Term, globals, scopes, name, namespace)
+                resolve(NameKind::Term, globals, scopes, name, namespace.as_deref())
             },
             Ok(Res::Local(_))
         ),
@@ -1980,7 +1984,7 @@ fn resolve<'a>(
     globals: &GlobalScope,
     scopes: impl Iterator<Item = &'a Scope>,
     provided_symbol_name: &Ident,
-    provided_namespace_name: &Option<Box<[Ident]>>,
+    provided_namespace_name: Option<&[Ident]>,
 ) -> Result<Res, Error> {
     if let Some(value) = check_all_scopes(
         kind,
@@ -2069,7 +2073,7 @@ fn check_all_scopes<'a>(
     kind: NameKind,
     globals: &GlobalScope,
     provided_symbol_name: &Ident,
-    provided_namespace_name: &Option<Box<[Ident]>>,
+    provided_namespace_name: Option<&[Ident]>,
     scopes: impl Iterator<Item = &'a Scope>,
 ) -> Option<Result<Res, Error>> {
     let mut vars = true;
@@ -2113,7 +2117,7 @@ fn check_scoped_resolutions(
     kind: NameKind,
     globals: &GlobalScope,
     provided_symbol_name: &Ident,
-    provided_namespace_name: &Option<Box<[Ident]>>,
+    provided_namespace_name: Option<&[Ident]>,
     vars: &mut bool,
     scope: &Scope,
 ) -> Option<Result<Res, Error>> {
@@ -2205,7 +2209,7 @@ fn ambiguous_symbol_error(
 fn find_symbol_in_namespaces<T, O>(
     kind: NameKind,
     globals: &GlobalScope,
-    provided_namespace_name: &Option<Box<[Ident]>>,
+    provided_namespace_name: Option<&[Ident]>,
     provided_symbol_name: &Ident,
     namespaces_to_search: T,
     aliases: &FxHashMap<Vec<Rc<str>>, Vec<(NamespaceId, O)>>,
@@ -2231,7 +2235,7 @@ where
             find_symbol_in_namespace(
                 kind,
                 globals,
-                &provided_namespace_name.as_ref().map(|x| &x[1..]),
+                provided_namespace_name.as_ref().map(|x| &x[1..]),
                 provided_symbol_name,
                 &mut candidates,
                 open.0,
@@ -2274,7 +2278,7 @@ where
 fn find_symbol_in_namespace<O>(
     kind: NameKind,
     globals: &GlobalScope,
-    provided_namespace_name: &Option<impl Idents>,
+    provided_namespace_name: Option<&[Ident]>,
     provided_symbol_name: &Ident,
     candidates: &mut FxHashMap<Res, O>,
     candidate_namespace_id: NamespaceId,
diff --git a/compiler/qsc_hir/src/global.rs b/compiler/qsc_hir/src/global.rs
index d4afe8fe..32622562 100644
--- a/compiler/qsc_hir/src/global.rs
+++ b/compiler/qsc_hir/src/global.rs
@@ -219,7 +219,7 @@ impl PackageIter<'_> {
     }
 }
 
-impl<'a> Iterator for PackageIter<'a> {
+impl Iterator for PackageIter<'_> {
     type Item = Global;
 
     fn next(&mut self) -> Option<Self::Item> {
diff --git a/compiler/qsc_hir/src/hir.rs b/compiler/qsc_hir/src/hir.rs
index 5c22bdd0..ade89e54 100644
--- a/compiler/qsc_hir/src/hir.rs
+++ b/compiler/qsc_hir/src/hir.rs
@@ -702,13 +702,19 @@ impl Display for ExprKind {
             ExprKind::Field(expr, field) => display_field(indent, expr, field)?,
             ExprKind::For(iter, iterable, body) => display_for(indent, iter, iterable, body)?,
             ExprKind::Hole => write!(indent, "Hole")?,
-            ExprKind::If(cond, body, els) => display_if(indent, cond, body, els)?,
+            ExprKind::If(cond, body, els) => display_if(indent, cond, body, els.as_deref())?,
             ExprKind::Index(array, index) => display_index(indent, array, index)?,
             ExprKind::Lit(lit) => write!(indent, "Lit: {lit}")?,
-            ExprKind::Range(start, step, end) => display_range(indent, start, step, end)?,
-            ExprKind::Repeat(repeat, until, fixup) => display_repeat(indent, repeat, until, fixup)?,
+            ExprKind::Range(start, step, end) => {
+                display_range(indent, start.as_deref(), step.as_deref(), end.as_deref())?;
+            }
+            ExprKind::Repeat(repeat, until, fixup) => {
+                display_repeat(indent, repeat, until, fixup.as_ref())?;
+            }
             ExprKind::Return(e) => write!(indent, "Return: {e}")?,
-            ExprKind::Struct(name, copy, fields) => display_struct(indent, name, copy, fields)?,
+            ExprKind::Struct(name, copy, fields) => {
+                display_struct(indent, name, copy.as_deref(), fields)?;
+            }
             ExprKind::String(components) => display_string(indent, components)?,
             ExprKind::UpdateIndex(expr1, expr2, expr3) => {
                 display_update_index(indent, expr1, expr2, expr3)?;
@@ -866,7 +872,7 @@ fn display_if(
     mut indent: Indented<Formatter>,
     cond: &Expr,
     body: &Expr,
-    els: &Option<Box<Expr>>,
+    els: Option<&Expr>,
 ) -> fmt::Result {
     write!(indent, "If:")?;
     indent = set_indentation(indent, 1);
@@ -888,9 +894,9 @@ fn display_index(mut indent: Indented<Formatter>, array: &Expr, index: &Expr) ->
 
 fn display_range(
     mut indent: Indented<Formatter>,
-    start: &Option<Box<Expr>>,
-    step: &Option<Box<Expr>>,
-    end: &Option<Box<Expr>>,
+    start: Option<&Expr>,
+    step: Option<&Expr>,
+    end: Option<&Expr>,
 ) -> fmt::Result {
     write!(indent, "Range:")?;
     indent = set_indentation(indent, 1);
@@ -913,7 +919,7 @@ fn display_repeat(
     mut indent: Indented<Formatter>,
     repeat: &Block,
     until: &Expr,
-    fixup: &Option<Block>,
+    fixup: Option<&Block>,
 ) -> fmt::Result {
     write!(indent, "Repeat:")?;
     indent = set_indentation(indent, 1);
@@ -929,7 +935,7 @@ fn display_repeat(
 fn display_struct(
     mut indent: Indented<Formatter>,
     name: &Res,
-    copy: &Option<Box<Expr>>,
+    copy: Option<&Expr>,
     fields: &[Box<FieldAssign>],
 ) -> fmt::Result {
     write!(indent, "Struct ({name}):")?;
diff --git a/compiler/qsc_parse/src/lex/raw.rs b/compiler/qsc_parse/src/lex/raw.rs
index 8cf1c0f7..b7023fbb 100644
--- a/compiler/qsc_parse/src/lex/raw.rs
+++ b/compiler/qsc_parse/src/lex/raw.rs
@@ -319,10 +319,7 @@ impl<'a> Lexer<'a> {
     fn string(&mut self, c: char) -> Option<TokenKind> {
         let kind = self.start_string(c)?;
 
-        while self
-            .first()
-            .map_or(false, |c| !is_string_terminator(kind, c))
-        {
+        while self.first().is_some_and(|c| !is_string_terminator(kind, c)) {
             self.eat_while(|c| c != '\\' && !is_string_terminator(kind, c));
             if self.next_if_eq('\\') {
                 self.chars.next();
diff --git a/compiler/qsc_passes/src/conjugate_invert.rs b/compiler/qsc_passes/src/conjugate_invert.rs
index 72530643..607e48e6 100644
--- a/compiler/qsc_passes/src/conjugate_invert.rs
+++ b/compiler/qsc_passes/src/conjugate_invert.rs
@@ -67,7 +67,7 @@ struct ConjugateElim<'a> {
     errors: Vec<Error>,
 }
 
-impl<'a> MutVisitor for ConjugateElim<'a> {
+impl MutVisitor for ConjugateElim<'_> {
     fn visit_expr(&mut self, expr: &mut Expr) {
         match take(&mut expr.kind) {
             ExprKind::Conjugate(within, apply) => {
diff --git a/compiler/qsc_passes/src/invert_block.rs b/compiler/qsc_passes/src/invert_block.rs
index fa2e1a06..b655fe58 100644
--- a/compiler/qsc_passes/src/invert_block.rs
+++ b/compiler/qsc_passes/src/invert_block.rs
@@ -43,7 +43,7 @@ struct BlockInverter<'a> {
     should_reverse_loop: bool,
 }
 
-impl<'a> MutVisitor for BlockInverter<'a> {
+impl MutVisitor for BlockInverter<'_> {
     fn visit_block(&mut self, block: &mut Block) {
         // Each block is split into classical and quantum statements based on the presence of operation
         // calls, so that the quantum statements can be reversed.
@@ -80,7 +80,7 @@ impl<'a> MutVisitor for BlockInverter<'a> {
     }
 }
 
-impl<'a> BlockInverter<'a> {
+impl BlockInverter<'_> {
     fn reverse_loop(&mut self, pat: &Pat, iterable: &Expr, block: &Block) -> Expr {
         let mut wrapper = Block {
             id: NodeId::default(),
diff --git a/compiler/qsc_passes/src/logic_sep.rs b/compiler/qsc_passes/src/logic_sep.rs
index 8852f229..371ae4ae 100644
--- a/compiler/qsc_passes/src/logic_sep.rs
+++ b/compiler/qsc_passes/src/logic_sep.rs
@@ -115,7 +115,7 @@ impl SepCheck {
         prior: bool,
         cond: &Expr,
         then_expr: &Expr,
-        else_expr: &Option<Box<Expr>>,
+        else_expr: Option<&Expr>,
     ) -> bool {
         self.op_call_allowed = false;
         self.visit_expr(cond);
@@ -172,7 +172,7 @@ impl SepCheck {
                 self.handle_block(loop_block)
             }
             ExprKind::If(cond, then_expr, else_expr) => {
-                self.handle_if_expr(prior, cond, then_expr, else_expr)
+                self.handle_if_expr(prior, cond, then_expr, else_expr.as_deref())
             }
 
             ExprKind::Array(_)
diff --git a/compiler/qsc_passes/src/spec_gen.rs b/compiler/qsc_passes/src/spec_gen.rs
index a4774c47..63ab19cc 100644
--- a/compiler/qsc_passes/src/spec_gen.rs
+++ b/compiler/qsc_passes/src/spec_gen.rs
@@ -162,7 +162,7 @@ struct SpecImplPass<'a> {
     is_codegen_intrinsic: bool,
 }
 
-impl<'a> SpecImplPass<'a> {
+impl SpecImplPass<'_> {
     fn ctl_distrib(&mut self, spec_decl: &mut SpecDecl, block: &Block) {
         let ctls_id = self.assigner.next_node();
 
@@ -214,7 +214,7 @@ impl<'a> SpecImplPass<'a> {
     }
 }
 
-impl<'a> MutVisitor for SpecImplPass<'a> {
+impl MutVisitor for SpecImplPass<'_> {
     fn visit_item(&mut self, item: &mut Item) {
         self.is_codegen_intrinsic = item.attrs.contains(&Attr::SimulatableIntrinsic);
         walk_item(self, item);
diff --git a/compiler/qsc_qasm3/src/oqasm_helpers.rs b/compiler/qsc_qasm3/src/oqasm_helpers.rs
index 8ef14832..bdfbca7f 100644
--- a/compiler/qsc_qasm3/src/oqasm_helpers.rs
+++ b/compiler/qsc_qasm3/src/oqasm_helpers.rs
@@ -41,7 +41,6 @@ pub(crate) fn span_for_syntax_token(token: &oq3_syntax::SyntaxToken) -> Span {
 /// panic if the value is too large to fit in the target type.
 ///
 /// Values may be truncated or rounded as necessary.
-
 pub(crate) fn safe_u128_to_f64(value: u128) -> Option<f64> {
     if value <= u128::from(i64::MAX as u64) {
         let value = i64::try_from(value).ok()?;
diff --git a/compiler/qsc_qasm3/src/runtime.rs b/compiler/qsc_qasm3/src/runtime.rs
index c06c6095..db19ec12 100644
--- a/compiler/qsc_qasm3/src/runtime.rs
+++ b/compiler/qsc_qasm3/src/runtime.rs
@@ -12,7 +12,7 @@ use qsc::{
 /// These functions are not part of the QASM3 standard, but are used to implement
 /// utility fuctions that would be cumbersome to implement building the AST
 /// directly.
-
+///
 /// The POW function is used to implement the `pow` modifier in QASM3 for integers.
 const POW: &str = "
 operation __Pow__<'T>(N: Int, op: ('T => Unit is Adj), target : 'T) : Unit is Adj {
diff --git a/compiler/qsc_qasm3/src/symbols.rs b/compiler/qsc_qasm3/src/symbols.rs
index ec49dfaa..428ecb40 100644
--- a/compiler/qsc_qasm3/src/symbols.rs
+++ b/compiler/qsc_qasm3/src/symbols.rs
@@ -10,9 +10,8 @@ use rustc_hash::FxHashMap;
 /// means that we need to keep track of the input and output symbols in the
 /// program. Additionally, we need to keep track of the types of the symbols
 /// in the program for type checking.
-/// Q# and QASM have different type systems, so we track the QASM semantic
-/// type in addition to the corresponding Q# type.
-
+/// Q# and QASM have different type systems, so we track the QASM semantic.
+///
 /// A symbol ID is a unique identifier for a symbol in the symbol table.
 /// This is used to look up symbols in the symbol table.
 /// Every symbol in the symbol table has a unique ID.
diff --git a/compiler/qsc_rca/src/core.rs b/compiler/qsc_rca/src/core.rs
index 60462f0d..a1bf2e66 100644
--- a/compiler/qsc_rca/src/core.rs
+++ b/compiler/qsc_rca/src/core.rs
@@ -694,9 +694,8 @@ impl<'a> Analyzer<'a> {
         // runtime features are aggregated.
         let is_any_sub_expr_dynamic = condition_expr_compute_kind.is_dynamic()
             || body_expr_compute_kind.is_dynamic()
-            || otherwise_expr_id.map_or(false, |e| {
-                application_instance.get_expr_compute_kind(e).is_dynamic()
-            });
+            || otherwise_expr_id
+                .is_some_and(|e| application_instance.get_expr_compute_kind(e).is_dynamic());
         if is_any_sub_expr_dynamic {
             let dynamic_value_kind = if matches!(expr_type, Ty::Array(..)) {
                 // An array coming from a dynamic conditional should be treated as dynamic in length
diff --git a/language_service/src/hover.rs b/language_service/src/hover.rs
index 954a4faa..2c52e1b5 100644
--- a/language_service/src/hover.rs
+++ b/language_service/src/hover.rs
@@ -113,7 +113,7 @@ impl<'a> Handler<'a> for HoverGenerator<'a> {
             &LocalKind::TypeParam,
             &code,
             &def_name.name,
-            &callable_name,
+            callable_name.as_deref(),
             &context.current_item_doc,
         );
         self.hover = Some(Hover {
@@ -135,7 +135,7 @@ impl<'a> Handler<'a> for HoverGenerator<'a> {
             &LocalKind::TypeParam,
             &code,
             &reference.name,
-            &callable_name,
+            callable_name.as_deref(),
             &context.current_item_doc,
         );
         self.hover = Some(Hover {
@@ -257,7 +257,7 @@ impl<'a> Handler<'a> for HoverGenerator<'a> {
             &kind,
             &code,
             &ident.name,
-            &callable_name,
+            callable_name.as_deref(),
             &context.current_item_doc,
         );
         self.hover = Some(Hover {
@@ -287,7 +287,7 @@ impl<'a> Handler<'a> for HoverGenerator<'a> {
             &kind,
             &code,
             local_name,
-            &callable_name,
+            callable_name.as_deref(),
             &context.current_item_doc,
         );
         self.hover = Some(Hover {
@@ -356,15 +356,13 @@ fn display_local(
     param_kind: &LocalKind,
     markdown: &String,
     local_name: &str,
-    callable_name: &Option<Rc<str>>,
+    callable_name: Option<&str>,
     callable_doc: &str,
 ) -> String {
     match param_kind {
         LocalKind::Param => {
             let param_doc = parse_doc_for_param(callable_doc, local_name);
-            let callable_name = callable_name
-                .as_ref()
-                .expect("param should have a callable name");
+            let callable_name = callable_name.expect("param should have a callable name");
             with_doc(
                 &param_doc,
                 format!("parameter of `{callable_name}`\n{markdown}",),
@@ -372,9 +370,7 @@ fn display_local(
         }
         LocalKind::TypeParam => {
             let param_doc = parse_doc_for_param(callable_doc, local_name);
-            let callable_name = callable_name
-                .as_ref()
-                .expect("type param should have a callable name");
+            let callable_name = callable_name.expect("type param should have a callable name");
             with_doc(
                 &param_doc,
                 format!("type parameter of `{callable_name}`\n{markdown}",),
diff --git a/language_service/src/name_locator.rs b/language_service/src/name_locator.rs
index 5243b56f..1c263905 100644
--- a/language_service/src/name_locator.rs
+++ b/language_service/src/name_locator.rs
@@ -169,7 +169,7 @@ impl<'inner, 'package, T: Handler<'package>> Locator<'inner, 'package, T> {
     }
 }
 
-impl<'inner, 'package, T: Handler<'package>> Visitor<'package> for Locator<'inner, 'package, T> {
+impl<'package, T: Handler<'package>> Visitor<'package> for Locator<'_, 'package, T> {
     fn visit_attr(&mut self, attr: &'package ast::Attr) {
         if attr.name.span.contains(self.offset) {
             self.inner.at_attr_ref(&attr.name);
diff --git a/language_service/src/references.rs b/language_service/src/references.rs
index 4f7bc4cf..48de7bdf 100644
--- a/language_service/src/references.rs
+++ b/language_service/src/references.rs
@@ -340,7 +340,7 @@ struct FindItemRefs<'a> {
     locations: Vec<Span>,
 }
 
-impl<'a> Visitor<'_> for FindItemRefs<'a> {
+impl Visitor<'_> for FindItemRefs<'_> {
     fn visit_path(&mut self, path: &ast::Path) {
         let res = self.compilation.get_res(path.id);
         if let Some(resolve::Res::Item(item_id, _)) = res {
@@ -364,7 +364,7 @@ impl<'a> Visitor<'_> for FindItemRefs<'a> {
     }
 }
 
-impl<'a> FindItemRefs<'a> {
+impl FindItemRefs<'_> {
     fn eq(&mut self, item_id: &hir::ItemId) -> bool {
         item_id.item == self.item_id.item
             && item_id.package.unwrap_or(self.compilation.user_package_id)
@@ -379,7 +379,7 @@ struct FindFieldRefs<'a> {
     locations: Vec<Span>,
 }
 
-impl<'a> Visitor<'_> for FindFieldRefs<'a> {
+impl Visitor<'_> for FindFieldRefs<'_> {
     fn visit_path(&mut self, path: &ast::Path) {
         if let Some((_, parts)) =
             resolve::path_as_field_accessor(&self.compilation.user_unit().ast.names, path)
@@ -435,7 +435,7 @@ impl<'a> Visitor<'_> for FindFieldRefs<'a> {
     }
 }
 
-impl<'a> FindFieldRefs<'a> {
+impl FindFieldRefs<'_> {
     fn eq(&mut self, item_id: &hir::ItemId) -> bool {
         item_id.item == self.ty_item_id.item
             && item_id.package.unwrap_or(self.compilation.user_package_id)
@@ -511,7 +511,7 @@ struct FindTyParamLocations<'a> {
     locations: Vec<Span>,
 }
 
-impl<'a> Visitor<'_> for FindTyParamLocations<'a> {
+impl Visitor<'_> for FindTyParamLocations<'_> {
     fn visit_callable_decl(&mut self, decl: &ast::CallableDecl) {
         if self.include_declaration {
             decl.generics.iter().for_each(|p| {
diff --git a/pip/src/fs.rs b/pip/src/fs.rs
index 453a43ac..6a79d017 100644
--- a/pip/src/fs.rs
+++ b/pip/src/fs.rs
@@ -104,8 +104,7 @@ impl FileSystem for Py<'_> {
 }
 
 fn read_file(py: Python, read_file: &PyObject, path: &Path) -> PyResult<(Arc<str>, Arc<str>)> {
-    let read_file_result =
-        read_file.call1(py, PyTuple::new_bound(py, &[path.to_string_lossy()]))?;
+    let read_file_result = read_file.call1(py, PyTuple::new(py, &[path.to_string_lossy()])?)?;
 
     let tuple = read_file_result.downcast_bound::<PyTuple>(py)?;
 
@@ -114,7 +113,7 @@ fn read_file(py: Python, read_file: &PyObject, path: &Path) -> PyResult<(Arc<str
 
 fn list_directory(py: Python, list_directory: &PyObject, path: &Path) -> PyResult<Vec<Entry>> {
     let list_directory_result =
-        list_directory.call1(py, PyTuple::new_bound(py, &[path.to_string_lossy()]))?;
+        list_directory.call1(py, PyTuple::new(py, &[path.to_string_lossy()])?)?;
 
     list_directory_result
         .downcast_bound::<PyList>(py)?
@@ -147,7 +146,7 @@ fn resolve_path(
 ) -> PyResult<PathBuf> {
     let resolve_path_result = resolve_path.call1(
         py,
-        PyTuple::new_bound(py, &[base.to_string_lossy(), path.to_string_lossy()]),
+        PyTuple::new(py, &[base.to_string_lossy(), path.to_string_lossy()])?,
     )?;
 
     Ok(PathBuf::from(
@@ -167,7 +166,7 @@ fn fetch_github(
     path: &str,
 ) -> PyResult<Arc<str>> {
     let fetch_github_result =
-        fetch_github.call1(py, PyTuple::new_bound(py, [owner, repo, r#ref, path]))?;
+        fetch_github.call1(py, PyTuple::new(py, [owner, repo, r#ref, path])?)?;
 
     Ok(fetch_github_result
         .downcast_bound::<PyString>(py)?
@@ -191,7 +190,7 @@ fn get_dict_string<'a>(dict: &Bound<'a, PyDict>, key: &'a str) -> PyResult<Bound
 }
 
 fn diagnostic_from(py: Python<'_>, err: &PyErr) -> miette::Report {
-    if let Some(traceback) = err.traceback_bound(py) {
+    if let Some(traceback) = err.traceback(py) {
         match traceback.format() {
             Ok(traceback) => miette!(format!("{err}\n{traceback}",)),
             Err(traceback_err) => {
diff --git a/pip/src/interop.rs b/pip/src/interop.rs
index 7c961a6d..3f3fb75d 100644
--- a/pip/src/interop.rs
+++ b/pip/src/interop.rs
@@ -88,7 +88,7 @@ pub fn run_qasm3(
 ) -> PyResult<PyObject> {
     let mut receiver = OptionalCallbackReceiver { callback, py };
 
-    let kwargs = kwargs.unwrap_or_else(|| PyDict::new_bound(py));
+    let kwargs = kwargs.unwrap_or_else(|| PyDict::new(py));
 
     let target = get_target_profile(&kwargs)?;
     let operation_name = get_operation_name(&kwargs)?;
@@ -120,11 +120,7 @@ pub fn run_qasm3(
         .map_err(|errors| map_entry_compilation_errors(errors, &signature))?;
 
     match run_ast(&mut interpreter, &mut receiver, shots, seed) {
-        Ok(result) => Ok(PyList::new_bound(
-            py,
-            result.iter().map(|v| ValueWrapper(v.clone()).into_py(py)),
-        )
-        .into_py(py)),
+        Ok(result) => Ok(PyList::new(py, result.iter().map(|v| ValueWrapper(v.clone())))?.into()),
         Err(errors) => Err(QSharpError::new_err(format_errors(errors))),
     }
 }
@@ -166,7 +162,7 @@ pub(crate) fn resource_estimate_qasm3(
     fetch_github: Option<PyObject>,
     kwargs: Option<Bound<'_, PyDict>>,
 ) -> PyResult<String> {
-    let kwargs = kwargs.unwrap_or_else(|| PyDict::new_bound(py));
+    let kwargs = kwargs.unwrap_or_else(|| PyDict::new(py));
 
     let operation_name = get_operation_name(&kwargs)?;
     let search_path = get_search_path(&kwargs)?;
@@ -228,7 +224,7 @@ pub(crate) fn compile_qasm3_to_qir(
     fetch_github: Option<PyObject>,
     kwargs: Option<Bound<'_, PyDict>>,
 ) -> PyResult<String> {
-    let kwargs = kwargs.unwrap_or_else(|| PyDict::new_bound(py));
+    let kwargs = kwargs.unwrap_or_else(|| PyDict::new(py));
 
     let target = get_target_profile(&kwargs)?;
     let operation_name = get_operation_name(&kwargs)?;
@@ -367,7 +363,7 @@ pub(crate) fn compile_qasm3_to_qsharp(
     fetch_github: Option<PyObject>,
     kwargs: Option<Bound<'_, PyDict>>,
 ) -> PyResult<String> {
-    let kwargs = kwargs.unwrap_or_else(|| PyDict::new_bound(py));
+    let kwargs = kwargs.unwrap_or_else(|| PyDict::new(py));
 
     let operation_name = get_operation_name(&kwargs)?;
     let search_path = get_search_path(&kwargs)?;
diff --git a/pip/src/interpreter.rs b/pip/src/interpreter.rs
index 0a221409..537957f8 100644
--- a/pip/src/interpreter.rs
+++ b/pip/src/interpreter.rs
@@ -17,7 +17,8 @@ use pyo3::{
     create_exception,
     exceptions::{PyException, PyValueError},
     prelude::*,
-    types::{PyComplex, PyDict, PyList, PyString, PyTuple, PyType},
+    types::{PyDict, PyList, PyString, PyTuple, PyType},
+    IntoPyObjectExt,
 };
 use qsc::{
     fir::{self},
@@ -76,10 +77,10 @@ fn _native<'a>(py: Python<'a>, m: &Bound<'a, PyModule>) -> PyResult<()> {
     m.add_class::<Circuit>()?;
     m.add_class::<GlobalCallable>()?;
     m.add_function(wrap_pyfunction!(physical_estimates, m)?)?;
-    m.add("QSharpError", py.get_type_bound::<QSharpError>())?;
+    m.add("QSharpError", py.get_type::<QSharpError>())?;
     register_noisy_simulator_submodule(py, m)?;
     // QASM3 interop
-    m.add("QasmError", py.get_type_bound::<QasmError>())?;
+    m.add("QasmError", py.get_type::<QasmError>())?;
     m.add_function(wrap_pyfunction!(resource_estimate_qasm3, m)?)?;
     m.add_function(wrap_pyfunction!(run_qasm3, m)?)?;
     m.add_function(wrap_pyfunction!(compile_qasm3_to_qir, m)?)?;
@@ -338,7 +339,7 @@ impl Interpreter {
                         create_py_callable(py, make_callable, &namespace, &name, val)?;
                     }
                 }
-                Ok(ValueWrapper(value).into_py(py))
+                Ok(ValueWrapper(value).into_pyobject(py)?.unbind())
             }
             Err(errors) => Err(QSharpError::new_err(format_errors(errors))),
         }
@@ -368,8 +369,8 @@ impl Interpreter {
     ///
     /// This circuit will contain the gates that have been applied
     /// in the simulator up to the current point.
-    fn dump_circuit(&mut self, py: Python) -> PyObject {
-        Circuit(self.interpreter.get_circuit()).into_py(py)
+    fn dump_circuit(&mut self, py: Python) -> PyResult<PyObject> {
+        Circuit(self.interpreter.get_circuit()).into_py_any(py)
     }
 
     #[pyo3(signature=(entry_expr=None, callback=None, noise=None))]
@@ -391,7 +392,7 @@ impl Interpreter {
         };
 
         match self.interpreter.run(&mut receiver, entry_expr, noise) {
-            Ok(value) => Ok(ValueWrapper(value).into_py(py)),
+            Ok(value) => Ok(ValueWrapper(value).into_pyobject(py)?.unbind()),
             Err(errors) => Err(QSharpError::new_err(format_errors(errors))),
         }
     }
@@ -441,7 +442,7 @@ impl Interpreter {
         };
 
         match self.interpreter.invoke(&mut receiver, callable.0, args) {
-            Ok(value) => Ok(ValueWrapper(value).into_py(py)),
+            Ok(value) => Ok(ValueWrapper(value).into_pyobject(py)?.unbind()),
             Err(errors) => Err(QSharpError::new_err(format_errors(errors))),
         }
     }
@@ -481,7 +482,7 @@ impl Interpreter {
         };
 
         match self.interpreter.circuit(entrypoint, false) {
-            Ok(circuit) => Ok(Circuit(circuit).into_py(py)),
+            Ok(circuit) => Circuit(circuit).into_py_any(py),
             Err(errors) => Err(QSharpError::new_err(format_errors(errors))),
         }
     }
@@ -530,7 +531,7 @@ impl Interpreter {
     ) -> PyResult<PyObject> {
         let mut receiver = OptionalCallbackReceiver { callback, py };
 
-        let kwargs = kwargs.unwrap_or_else(|| PyDict::new_bound(py));
+        let kwargs = kwargs.unwrap_or_else(|| PyDict::new(py));
 
         let operation_name = crate::interop::get_operation_name(&kwargs)?;
         let seed = crate::interop::get_seed(&kwargs);
@@ -570,15 +571,13 @@ impl Interpreter {
                     .map_err(|errors| map_entry_compilation_errors(errors, &signature))?;
 
                 match run_ast(&mut self.interpreter, &mut receiver, shots, seed) {
-                    Ok(result) => Ok(PyList::new_bound(
-                        py,
-                        result.iter().map(|v| ValueWrapper(v.clone()).into_py(py)),
-                    )
-                    .into_py(py)),
+                    Ok(result) => {
+                        Ok(PyList::new(py, result.iter().map(|v| ValueWrapper(v.clone())))?.into())
+                    }
                     Err(errors) => Err(QSharpError::new_err(format_errors(errors))),
                 }
             }
-            _ => Ok(ValueWrapper(value).into_py(py)),
+            _ => Ok(ValueWrapper(value).into_pyobject(py)?.unbind()),
         }
     }
 }
@@ -776,22 +775,8 @@ pub(crate) struct StateDumpData(pub(crate) DisplayableState);
 #[pymethods]
 impl StateDumpData {
     fn get_dict<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, PyDict>> {
-        PyDict::from_sequence_bound(&PyList::new_bound(
-            py,
-            self.0
-                 .0
-                .iter()
-                .map(|(k, v)| {
-                    PyTuple::new_bound(
-                        py,
-                        &[
-                            k.clone().into_py(py),
-                            PyComplex::from_doubles_bound(py, v.re, v.im).into(),
-                        ],
-                    )
-                })
-                .collect::<Vec<_>>(),
-        ))
+        let dict = rustc_hash::FxHashMap::from_iter(self.0 .0.clone());
+        dict.into_pyobject(py)
     }
 
     #[getter]
@@ -870,40 +855,45 @@ pub(crate) enum Pauli {
 // Mapping of Q# value types to Python value types.
 pub(crate) struct ValueWrapper(pub(crate) Value);
 
-impl IntoPy<PyObject> for ValueWrapper {
-    fn into_py(self, py: Python) -> PyObject {
+impl<'py> IntoPyObject<'py> for ValueWrapper {
+    type Target = PyAny;
+
+    type Output = Bound<'py, Self::Target>;
+
+    type Error = pyo3::PyErr;
+
+    fn into_pyobject(self, py: Python<'py>) -> std::result::Result<Self::Output, Self::Error> {
         match self.0 {
-            Value::BigInt(val) => val.into_py(py),
-            Value::Int(val) => val.into_py(py),
-            Value::Double(val) => val.into_py(py),
-            Value::Bool(val) => val.into_py(py),
-            Value::String(val) => val.into_py(py),
+            Value::Int(val) => val.into_bound_py_any(py),
+            Value::BigInt(val) => val.into_bound_py_any(py),
+            Value::Double(val) => val.into_bound_py_any(py),
+            Value::Bool(val) => val.into_bound_py_any(py),
+            Value::String(val) => val.into_bound_py_any(py),
             Value::Result(val) => if val.unwrap_bool() {
                 Result::One
             } else {
                 Result::Zero
             }
-            .into_py(py),
+            .into_bound_py_any(py),
             Value::Pauli(val) => match val {
-                fir::Pauli::I => Pauli::I.into_py(py),
-                fir::Pauli::X => Pauli::X.into_py(py),
-                fir::Pauli::Y => Pauli::Y.into_py(py),
-                fir::Pauli::Z => Pauli::Z.into_py(py),
+                fir::Pauli::I => Pauli::I.into_bound_py_any(py),
+                fir::Pauli::X => Pauli::X.into_bound_py_any(py),
+                fir::Pauli::Y => Pauli::Y.into_bound_py_any(py),
+                fir::Pauli::Z => Pauli::Z.into_bound_py_any(py),
             },
             Value::Tuple(val) => {
                 if val.is_empty() {
                     // Special case Value::unit as None
-                    py.None()
+                    Ok(py.None().into_bound(py))
                 } else {
-                    PyTuple::new_bound(py, val.iter().map(|v| ValueWrapper(v.clone()).into_py(py)))
-                        .into_py(py)
+                    PyTuple::new(py, val.iter().map(|v| ValueWrapper(v.clone())))?
+                        .into_bound_py_any(py)
                 }
             }
             Value::Array(val) => {
-                PyList::new_bound(py, val.iter().map(|v| ValueWrapper(v.clone()).into_py(py)))
-                    .into_py(py)
+                PyList::new(py, val.iter().map(|v| ValueWrapper(v.clone())))?.into_bound_py_any(py)
             }
-            _ => format!("<{}> {}", Value::type_name(&self.0), &self.0).into_py(py),
+            _ => format!("<{}> {}", Value::type_name(&self.0), &self.0).into_bound_py_any(py),
         }
     }
 }
@@ -924,10 +914,11 @@ impl Receiver for OptionalCallbackReceiver<'_> {
             callback
                 .call1(
                     self.py,
-                    PyTuple::new_bound(
+                    PyTuple::new(
                         self.py,
                         &[Py::new(self.py, Output(out)).expect("should be able to create output")],
-                    ),
+                    )
+                    .map_err(|_| Error)?,
                 )
                 .map_err(|_| Error)?;
         }
@@ -940,10 +931,11 @@ impl Receiver for OptionalCallbackReceiver<'_> {
             callback
                 .call1(
                     self.py,
-                    PyTuple::new_bound(
+                    PyTuple::new(
                         self.py,
                         &[Py::new(self.py, Output(out)).expect("should be able to create output")],
-                    ),
+                    )
+                    .map_err(|_| Error)?,
                 )
                 .map_err(|_| Error)?;
         }
@@ -956,10 +948,11 @@ impl Receiver for OptionalCallbackReceiver<'_> {
             callback
                 .call1(
                     self.py,
-                    PyTuple::new_bound(
+                    PyTuple::new(
                         self.py,
                         &[Py::new(self.py, Output(out)).expect("should be able to create output")],
-                    ),
+                    )
+                    .map_err(|_| Error)?,
                 )
                 .map_err(|_| Error)?;
         }
@@ -1043,8 +1036,8 @@ fn create_py_callable(
 
     let args = (
         Py::new(py, GlobalCallable::from(val)).expect("should be able to create callable"), // callable id
-        PyList::new_bound(py, namespace.iter().map(ToString::to_string)), // namespace as string array
-        PyString::new_bound(py, name),                                    // name of callable
+        PyList::new(py, namespace.iter().map(ToString::to_string))?, // namespace as string array
+        PyString::new(py, name),                                     // name of callable
     );
 
     // Call into the Python layer to create the function wrapping the callable invocation.
diff --git a/pip/src/noisy_simulator.rs b/pip/src/noisy_simulator.rs
index d5369407..e5e11f90 100644
--- a/pip/src/noisy_simulator.rs
+++ b/pip/src/noisy_simulator.rs
@@ -12,10 +12,7 @@ pub(crate) fn register_noisy_simulator_submodule<'a>(
     py: Python<'a>,
     m: &Bound<'a, PyModule>,
 ) -> PyResult<()> {
-    m.add(
-        "NoisySimulatorError",
-        py.get_type_bound::<NoisySimulatorError>(),
-    )?;
+    m.add("NoisySimulatorError", py.get_type::<NoisySimulatorError>())?;
     m.add_class::<Operation>()?;
     m.add_class::<Instrument>()?;
     m.add_class::<DensityMatrixSimulator>()?;
diff --git a/prereqs.py b/prereqs.py
index 8cc51fc0..50698c71 100755
--- a/prereqs.py
+++ b/prereqs.py
@@ -13,14 +13,14 @@ import tempfile
 import functools
 
 python_ver = (3, 11)  # Python support for Windows on ARM64 requires v3.11 or later
-rust_ver = (1, 82)  # Ensure Rust version 1.82 or later is installed
+rust_ver = (1, 84)  # Ensure Rust version 1.84 or later is installed
 node_ver = (
     18,
     17,
 )
 wasmpack_ver = (0, 12, 1)  # Latest tested wasm-pack version
-rust_fmt_ver = (1, 7, 1)  # Current version when Rust 1.82 shipped
-clippy_ver = (0, 1, 82)
+rust_fmt_ver = (1, 8, 0)  # Current version when Rust 1.84 shipped
+clippy_ver = (0, 1, 84)
 
 # Disable buffered output so that the log statements and subprocess output get interleaved in proper order
 print = functools.partial(print, flush=True)
diff --git a/resource_estimator/src/estimates/physical_estimation.rs b/resource_estimator/src/estimates/physical_estimation.rs
index 232c7c5d..e63bc5d7 100644
--- a/resource_estimator/src/estimates/physical_estimation.rs
+++ b/resource_estimator/src/estimates/physical_estimation.rs
@@ -645,7 +645,7 @@ impl<'a, F: Clone> FactoryForCycles<'a, F> {
     }
 }
 
-impl<'a, F: Factory + Clone> Ord for FactoryForCycles<'a, F> {
+impl<F: Factory + Clone> Ord for FactoryForCycles<'_, F> {
     fn cmp(&self, other: &Self) -> std::cmp::Ordering {
         self.factory
             .normalized_volume()
@@ -654,17 +654,17 @@ impl<'a, F: Factory + Clone> Ord for FactoryForCycles<'a, F> {
     }
 }
 
-impl<'a, F: Factory + Clone> PartialOrd for FactoryForCycles<'a, F> {
+impl<F: Factory + Clone> PartialOrd for FactoryForCycles<'_, F> {
     fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
         Some(self.cmp(other))
     }
 }
 
-impl<'a, F: Factory + Clone> PartialEq for FactoryForCycles<'a, F> {
+impl<F: Factory + Clone> PartialEq for FactoryForCycles<'_, F> {
     fn eq(&self, other: &Self) -> bool {
         (self.factory.normalized_volume(), self.num_cycles)
             == (other.factory.normalized_volume(), other.num_cycles)
     }
 }
 
-impl<'a, F: Factory + Clone> Eq for FactoryForCycles<'a, F> {}
+impl<F: Factory + Clone> Eq for FactoryForCycles<'_, F> {}
diff --git a/resource_estimator/src/estimates/physical_estimation/estimate_frontier.rs b/resource_estimator/src/estimates/physical_estimation/estimate_frontier.rs
index 15f15827..0f2fb1c5 100644
--- a/resource_estimator/src/estimates/physical_estimation/estimate_frontier.rs
+++ b/resource_estimator/src/estimates/physical_estimation/estimate_frontier.rs
@@ -216,11 +216,10 @@ impl<
 }
 
 impl<
-        'a,
         E: ErrorCorrection<Parameter = impl Clone>,
         B: FactoryBuilder<E, Factory = impl Factory<Parameter = E::Parameter> + Clone>,
         L: Overhead,
-    > Deref for EstimateFrontier<'a, E, B, L>
+    > Deref for EstimateFrontier<'_, E, B, L>
 {
     type Target = PhysicalResourceEstimation<E, B, L>;
 
diff --git a/resource_estimator/src/estimates/physical_estimation/estimate_without_restrictions.rs b/resource_estimator/src/estimates/physical_estimation/estimate_without_restrictions.rs
index b9534293..60fefe17 100644
--- a/resource_estimator/src/estimates/physical_estimation/estimate_without_restrictions.rs
+++ b/resource_estimator/src/estimates/physical_estimation/estimate_without_restrictions.rs
@@ -278,11 +278,10 @@ impl<
 }
 
 impl<
-        'a,
         E: ErrorCorrection<Parameter = impl Clone>,
         B: FactoryBuilder<E, Factory = impl Factory<Parameter = E::Parameter> + Clone>,
         L: Overhead,
-    > Deref for EstimateWithoutRestrictions<'a, E, B, L>
+    > Deref for EstimateWithoutRestrictions<'_, E, B, L>
 {
     type Target = PhysicalResourceEstimation<E, B, L>;
 
diff --git a/resource_estimator/src/system/modeling/tfactory.rs b/resource_estimator/src/system/modeling/tfactory.rs
index f47ed4b2..effaea77 100644
--- a/resource_estimator/src/system/modeling/tfactory.rs
+++ b/resource_estimator/src/system/modeling/tfactory.rs
@@ -26,7 +26,7 @@ pub enum TFactoryQubit<'a> {
     Physical(&'a PhysicalQubit),
 }
 
-impl<'a> TFactoryQubit<'a> {
+impl TFactoryQubit<'_> {
     pub fn physical_qubits(&self) -> u64 {
         match self {
             Self::Logical(qubit) => qubit.physical_qubits(),
@@ -286,7 +286,7 @@ pub struct TFactoryDistillationUnit<'a> {
     qubit_t_error_rate: f64,
 }
 
-impl<'a> fmt::Debug for TFactoryDistillationUnit<'a> {
+impl fmt::Debug for TFactoryDistillationUnit<'_> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("TFactoryDistillationUnit")
             .field("unit_type", &self.unit_type.to_string())
diff --git a/resource_estimator/src/system/serialization.rs b/resource_estimator/src/system/serialization.rs
index 891de1a3..a72af42f 100644
--- a/resource_estimator/src/system/serialization.rs
+++ b/resource_estimator/src/system/serialization.rs
@@ -44,7 +44,7 @@ pub(crate) mod time {
     ///
     /// This adds the `ns` prefix to all time values and serializes them as a
     /// string.
-    #[allow(clippy::trivially_copy_pass_by_ref)] // forced by serde interface
+    #[allow(clippy::trivially_copy_pass_by_ref, clippy::ref_option)] // forced by serde interface
     pub(crate) fn serialize<S: Serializer>(
         time: &Option<u64>,
         serializer: S,
diff --git a/wasm/src/debug_service.rs b/wasm/src/debug_service.rs
index aba559f3..0f67252a 100644
--- a/wasm/src/debug_service.rs
+++ b/wasm/src/debug_service.rs
@@ -153,8 +153,7 @@ impl DebugService {
                 success = false;
                 errors[0]
                     .stack_trace()
-                    .clone()
-                    .map(serde_json::Value::String)
+                    .map(|arg0: &std::string::String| serde_json::Value::String(arg0.clone()))
             }
         };
         if let Some(value) = msg {
diff --git a/wasm/src/diagnostic.rs b/wasm/src/diagnostic.rs
index b5c2e6dc..46cc634e 100644
--- a/wasm/src/diagnostic.rs
+++ b/wasm/src/diagnostic.rs
@@ -229,7 +229,7 @@ pub fn interpret_errors_into_qsharp_errors(errs: &[interpret::Error]) -> Vec<QSh
             let vsdiagnostic = VSDiagnostic::new(labels, &doc, err);
 
             let stack_trace = if let interpret::Error::Eval(_) = err {
-                err.stack_trace().clone()
+                err.stack_trace()
             } else {
                 None
             };
@@ -237,7 +237,7 @@ pub fn interpret_errors_into_qsharp_errors(errs: &[interpret::Error]) -> Vec<QSh
             QSharpError {
                 document: doc,
                 diagnostic: vsdiagnostic,
-                stack: stack_trace,
+                stack: stack_trace.cloned(),
             }
         })
         .collect()
diff --git a/wasm/src/lib.rs b/wasm/src/lib.rs
index e644fe6f..edc8fb0a 100644
--- a/wasm/src/lib.rs
+++ b/wasm/src/lib.rs
@@ -60,7 +60,7 @@ pub fn get_qir(program: ProgramConfig) -> Result<String, String> {
     let (source_map, capabilities, language_features, store, deps) =
         into_qsc_args(program, None).map_err(compile_errors_into_qsharp_errors_json)?;
 
-    _get_qir(
+    get_qir_(
         source_map,
         language_features,
         capabilities,
@@ -69,7 +69,7 @@ pub fn get_qir(program: ProgramConfig) -> Result<String, String> {
     )
 }
 
-pub(crate) fn _get_qir(
+pub(crate) fn get_qir_(
     sources: SourceMap,
     language_features: LanguageFeatures,
     capabilities: TargetCapabilityFlags,


Test patch:
diff --git a/compiler/qsc/src/interpret/debug/tests.rs b/compiler/qsc/src/interpret/debug/tests.rs
index 35b1e49c..ca311b2f 100644
--- a/compiler/qsc/src/interpret/debug/tests.rs
+++ b/compiler/qsc/src/interpret/debug/tests.rs
@@ -89,7 +89,6 @@ fn stack_traces_can_cross_eval_session_and_file_boundaries() {
         Err(e) => {
             let stack_trace = e[0]
                 .stack_trace()
-                .as_ref()
                 .expect("code should have a valid stack trace");
             let expectation = indoc! {r#"
                          Error: division by zero
@@ -161,7 +160,6 @@ fn stack_traces_can_cross_file_and_entry_boundaries() {
         Err(e) => {
             let stack_trace = e[0]
                 .stack_trace()
-                .as_ref()
                 .expect("code should have a valid stack trace");
             let expectation = indoc! {r#"
                          Error: division by zero
diff --git a/compiler/qsc_frontend/src/resolve/tests.rs b/compiler/qsc_frontend/src/resolve/tests.rs
index e010f0e9..853ead6a 100644
--- a/compiler/qsc_frontend/src/resolve/tests.rs
+++ b/compiler/qsc_frontend/src/resolve/tests.rs
@@ -173,7 +173,7 @@ impl Visitor<'_> for Renamer<'_> {
     }
 }
 
-impl<'a> Renamer<'a> {
+impl Renamer<'_> {
     fn find_namespace_id(&mut self, idents: &impl Idents) -> Option<NamespaceId> {
         let ns_id = self
             .namespaces
diff --git a/wasm/src/tests.rs b/wasm/src/tests.rs
index 3b6d79f0..260324a6 100644
--- a/wasm/src/tests.rs
+++ b/wasm/src/tests.rs
@@ -7,7 +7,7 @@ use qsc::{
     interpret, LanguageFeatures, PackageStore, PauliNoise, SourceMap, TargetCapabilityFlags,
 };
 
-use crate::_get_qir;
+use crate::get_qir_;
 
 use super::run_internal_with_features;
 
@@ -513,7 +513,7 @@ fn test_doc_gen() {
         } else if !filename.eq("index.md") {
             assert!(std::path::Path::new(&filename)
                 .extension()
-                .map_or(false, |ext| ext.eq_ignore_ascii_case("md")));
+                .is_some_and(|ext| ext.eq_ignore_ascii_case("md")));
             assert!(
                 text.starts_with("---\n"),
                 "file {name} does not start with metadata\ncontents: {text}"
@@ -542,5 +542,5 @@ fn code_with_errors_returns_errors() {
             "[{\"document\":\"test.qs\",\"diagnostic\":{\"range\":{\"start\":{\"line\":4,\"character\":16},\"end\":{\"line\":4,\"character\":19}},\"message\":\"syntax error: expected `;`, found keyword `let`\",\"severity\":\"error\",\"code\":\"Qsc.Parse.Token\"},\"stack\":null}]",
         )
     "#]]
-    .assert_debug_eq(&_get_qir(sources, language_features, capabilities, store, &[]));
+    .assert_debug_eq(&get_qir_(sources, language_features, capabilities, store, &[]));
 }