From 7637ff46510ffe93b4d1c3996a7178c6e52adb16 Mon Sep 17 00:00:00 2001
From: ShryukGrandhi <85529990+ShryukGrandhi@users.noreply.github.com>
Date: Thu, 22 Oct 2026 00:36:14 -0700
Subject: [PATCH 1/4] fix(linalg): drop std HashSet from ordered_iter_mut debug
check
Signed-off-by: ShryukGrandhi <85529990+ShryukGrandhi@users.noreply.github.com>
---
src/linalg/basic/matrix.rs | 29 ++++++++++++++++++++++++-----
1 file changed, 24 insertions(+), 5 deletions(-)
diff --git a/src/linalg/basic/matrix.rs b/src/linalg/basic/matrix.rs
index 2abf44a3..f70a931b 100644
--- a/src/linalg/basic/matrix.rs
+++ b/src/linalg/basic/matrix.rs
@@ -74,16 +74,18 @@ where
#[cfg(debug_assertions)]
{
let len = values.len();
- let mut seen = std::collections::HashSet::new();
for &o in &desired {
assert!(
o < len,
"iterator_mut: offset {o} out of bounds (len={len})"
);
- assert!(
- seen.insert(o),
- "iterator_mut: aliasing detected at offset {o}"
- );
+ }
+ // Sorted-`Vec` duplicate check instead of a `HashSet`, so that this
+ // check works with `alloc` only (no `std` hash collections).
+ let mut sorted_check = desired.clone();
+ sorted_check.sort_unstable();
+ if let Some(w) = sorted_check.windows(2).find(|w| w[0] == w[1]) {
+ panic!("iterator_mut: aliasing detected at offset {}", w[0]);
}
}
@@ -848,6 +850,23 @@ mod tests {
assert_eq!(vec![1, 4, 3, 4, 7, 6], *x.values);
}
+ #[cfg(debug_assertions)]
+ #[test]
+ #[should_panic(expected = "iterator_mut: aliasing detected at offset 1")]
+ fn test_ordered_iter_mut_detects_aliasing() {
+ // stride 1 < ncols 2: offsets of row 0 and row 1 overlap.
+ let mut values = vec![0, 1, 2];
+ let _ = ordered_iter_mut(&mut values, 1, 2, 2, false, 0);
+ }
+
+ #[cfg(debug_assertions)]
+ #[test]
+ #[should_panic(expected = "iterator_mut: offset 3 out of bounds (len=3)")]
+ fn test_ordered_iter_mut_detects_out_of_bounds() {
+ let mut values = vec![0, 1, 2];
+ let _ = ordered_iter_mut(&mut values, 2, 2, 2, false, 0);
+ }
+
#[test]
fn test_get_slice() {
let x = DenseMatrix::from_2d_array(&[&[1, 2, 3], &[4, 5, 6], &[7, 8, 9], &[10, 11, 12]])
From d5e4bfe1572d26f7e679210da7abc06f23bb0352 Mon Sep 17 00:00:00 2001
From: ShryukGrandhi <85529990+ShryukGrandhi@users.noreply.github.com>
Date: Fri, 23 Oct 2026 05:01:51 -0700
Subject: [PATCH 2/4] fix(linalg): reuse sorted offsets for ordered_iter_mut
alias check
Signed-off-by: ShryukGrandhi <85529990+ShryukGrandhi@users.noreply.github.com>
---
src/linalg/basic/matrix.rs | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/src/linalg/basic/matrix.rs b/src/linalg/basic/matrix.rs
index f70a931b..d8662463 100644
--- a/src/linalg/basic/matrix.rs
+++ b/src/linalg/basic/matrix.rs
@@ -34,7 +34,7 @@ use crate::error::Failed;
/// the sub-slice spans gaps). The traversal order is identical to the previous
/// raw-pointer implementation; only the borrow-proving mechanism changes.
///
-/// `debug_assert!`s verify the computed offsets are in-bounds and distinct
+/// Debug-only checks verify the computed offsets are in-bounds and distinct
/// (mirroring the old `#[cfg(debug_assertions)]` aliasing checks).
fn ordered_iter_mut<'b, T>(
values: &'b mut [T],
@@ -80,13 +80,6 @@ where
"iterator_mut: offset {o} out of bounds (len={len})"
);
}
- // Sorted-`Vec` duplicate check instead of a `HashSet`, so that this
- // check works with `alloc` only (no `std` hash collections).
- let mut sorted_check = desired.clone();
- sorted_check.sort_unstable();
- if let Some(w) = sorted_check.windows(2).find(|w| w[0] == w[1]) {
- panic!("iterator_mut: aliasing detected at offset {}", w[0]);
- }
}
// Fast path: the desired order is the natural storage order, so the slice
@@ -103,6 +96,14 @@ where
let mut sorted: Vec<(usize, usize)> =
desired.iter().enumerate().map(|(i, &o)| (o, i)).collect();
sorted.sort_unstable_by_key(|&(o, _)| o);
+ // Duplicate check on the sorted offsets instead of a `HashSet`, so that
+ // this check works with `alloc` only (no `std` hash collections).
+ #[cfg(debug_assertions)]
+ {
+ if let Some(w) = sorted.windows(2).find(|w| w[0].0 == w[1].0) {
+ panic!("iterator_mut: aliasing detected at offset {}", w[0].0);
+ }
+ }
let mut result: Vec