From 13b273649ca9daba15b2bea1ffb849a6c0eb8a89 Mon Sep 17 00:00:00 2001 From: Sungkeun Cho Date: Wed, 11 Feb 2026 06:09:05 +0900 Subject: [PATCH 1/3] Avoid index clone in next There is an avoidable `clone` in `next`. This commit introduces `next_for_mut`, which is similar to `next_for`, but updates the key in-place, and uses it in `next` instead. --- src/dimension/dimension_trait.rs | 19 ++++++++++++++++++- src/iterators/mod.rs | 6 ++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/dimension/dimension_trait.rs b/src/dimension/dimension_trait.rs index 3544a7f3c..007e4717f 100644 --- a/src/dimension/dimension_trait.rs +++ b/src/dimension/dimension_trait.rs @@ -195,7 +195,6 @@ pub trait Dimension: #[doc(hidden)] /// Iteration -- Use self as size, and return next index after `index` /// or None if there are no more. - // FIXME: use &Self for index or even &mut? #[inline] fn next_for(&self, index: Self) -> Option { @@ -217,6 +216,24 @@ pub trait Dimension: } } + #[doc(hidden)] + /// Iteration -- Similar to `next_for`, but addresses the index as mutable reference. + #[inline] + fn next_for_mut(&self, index: &mut Self) -> bool + { + let mut end_iteration = true; + for (&dim, ix) in zip(self.slice(), index.slice_mut()).rev() { + *ix += 1; + if *ix == dim { + *ix = 0; + } else { + end_iteration = false; + break; + } + } + !end_iteration + } + #[doc(hidden)] /// Iteration -- Use self as size, and create the next index after `index` /// Return false if iteration is done diff --git a/src/iterators/mod.rs b/src/iterators/mod.rs index f7892a8c9..8d2be943c 100644 --- a/src/iterators/mod.rs +++ b/src/iterators/mod.rs @@ -74,10 +74,12 @@ impl Iterator for Baseiter { let index = match self.index { None => return None, - Some(ref ix) => ix.clone(), + Some(ref mut ix) => ix, }; let offset = D::stride_offset(&index, &self.strides); - self.index = self.dim.next_for(index); + if !self.dim.next_for_mut(index) { + self.index = None; + } unsafe { Some(self.ptr.offset(offset)) } } From cc53dd2b44ccdbf988f072301cf915afd0d6c023 Mon Sep 17 00:00:00 2001 From: Sungkeun Cho Date: Thu, 12 Feb 2026 09:07:51 +0900 Subject: [PATCH 2/3] Rewrite next_for using next_for_mut --- src/dimension/dimension_trait.rs | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/dimension/dimension_trait.rs b/src/dimension/dimension_trait.rs index 007e4717f..3a406a097 100644 --- a/src/dimension/dimension_trait.rs +++ b/src/dimension/dimension_trait.rs @@ -196,20 +196,9 @@ pub trait Dimension: /// Iteration -- Use self as size, and return next index after `index` /// or None if there are no more. #[inline] - fn next_for(&self, index: Self) -> Option + fn next_for(&self, mut index: Self) -> Option { - let mut index = index; - let mut done = false; - for (&dim, ix) in zip(self.slice(), index.slice_mut()).rev() { - *ix += 1; - if *ix == dim { - *ix = 0; - } else { - done = true; - break; - } - } - if done { + if self.next_for_mut(&mut index) { Some(index) } else { None From d7e95616ed44bbf93006e5a61c4965e092fa2c3e Mon Sep 17 00:00:00 2001 From: Sungkeun Cho Date: Fri, 13 Feb 2026 07:12:09 +0900 Subject: [PATCH 3/3] Fix clippy error --- src/iterators/mod.rs | 2 +- src/partial.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/iterators/mod.rs b/src/iterators/mod.rs index 8d2be943c..d57a0d815 100644 --- a/src/iterators/mod.rs +++ b/src/iterators/mod.rs @@ -76,7 +76,7 @@ impl Iterator for Baseiter None => return None, Some(ref mut ix) => ix, }; - let offset = D::stride_offset(&index, &self.strides); + let offset = D::stride_offset(index, &self.strides); if !self.dim.next_for_mut(index) { self.index = None; } diff --git a/src/partial.rs b/src/partial.rs index dbaa0e105..e6ba64537 100644 --- a/src/partial.rs +++ b/src/partial.rs @@ -71,7 +71,7 @@ impl Partial // covers the whole output. if left.is_stub() { right - } else if left.ptr.wrapping_add(left.len) == right.ptr { + } else if ptr::eq(left.ptr.wrapping_add(left.len), right.ptr) { left.len += right.release_ownership(); left } else {