From 974f7f70eafa0f38873e05ca7532d4dac8c9be20 Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Mon, 26 Feb 2024 20:30:53 +0100 Subject: [PATCH 1/2] Fix nightly lints Co-authored-by: Adam Reichold --- src/array_serde.rs | 1 + src/arrayformat.rs | 3 ++- src/arraytraits.rs | 5 ++++- src/data_repr.rs | 2 ++ src/data_traits.rs | 1 + src/dimension/axes.rs | 7 ------- src/dimension/conversion.rs | 1 + src/dimension/dimension_trait.rs | 1 + src/dimension/dynindeximpl.rs | 2 ++ src/extension/nonnull.rs | 1 + src/free_functions.rs | 1 + src/impl_1d.rs | 1 + src/impl_constructors.rs | 1 + src/impl_methods.rs | 1 + src/impl_ops.rs | 1 - src/impl_owned_array.rs | 1 + src/iterators/mod.rs | 1 + src/linalg/impl_linalg.rs | 1 + src/numeric/impl_numeric.rs | 2 +- src/slice.rs | 1 + src/split_at.rs | 1 + src/stacking.rs | 1 + tests/iterators.rs | 2 +- 23 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/array_serde.rs b/src/array_serde.rs index f1c9e1219..a6f3c617c 100644 --- a/src/array_serde.rs +++ b/src/array_serde.rs @@ -12,6 +12,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::fmt; use std::marker::PhantomData; use alloc::format; +#[cfg(not(feature = "std"))] use alloc::vec::Vec; use crate::imp_prelude::*; diff --git a/src/arrayformat.rs b/src/arrayformat.rs index ae781df6a..ec5b041d9 100644 --- a/src/arrayformat.rs +++ b/src/arrayformat.rs @@ -285,8 +285,9 @@ where #[cfg(test)] mod formatting_with_omit { use itertools::Itertools; - use std::fmt; + #[cfg(not(feature = "std"))] use alloc::string::String; + #[cfg(not(feature = "std"))] use alloc::vec::Vec; use super::*; diff --git a/src/arraytraits.rs b/src/arraytraits.rs index 9aa45bde3..f45c8a1bd 100644 --- a/src/arraytraits.rs +++ b/src/arraytraits.rs @@ -6,9 +6,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[cfg(not(feature = "std"))] use alloc::boxed::Box; +#[cfg(not(feature = "std"))] use alloc::vec::Vec; -use std::iter::IntoIterator; use std::mem; use std::ops::{Index, IndexMut}; use std::{hash, mem::size_of}; @@ -115,6 +116,7 @@ where /// Return `true` if the array shapes and all elements of `self` and /// `rhs` are equal. Return `false` otherwise. +#[allow(clippy::unconditional_recursion)] // false positive impl<'a, A, B, S, S2, D> PartialEq<&'a ArrayBase> for ArrayBase where A: PartialEq, @@ -129,6 +131,7 @@ where /// Return `true` if the array shapes and all elements of `self` and /// `rhs` are equal. Return `false` otherwise. +#[allow(clippy::unconditional_recursion)] // false positive impl<'a, A, B, S, S2, D> PartialEq> for &'a ArrayBase where A: PartialEq, diff --git a/src/data_repr.rs b/src/data_repr.rs index 6630f9ddf..f740988f4 100644 --- a/src/data_repr.rs +++ b/src/data_repr.rs @@ -2,7 +2,9 @@ use std::mem; use std::mem::ManuallyDrop; use std::ptr::NonNull; use alloc::slice; +#[cfg(not(feature = "std"))] use alloc::borrow::ToOwned; +#[cfg(not(feature = "std"))] use alloc::vec::Vec; use crate::extension::nonnull; diff --git a/src/data_traits.rs b/src/data_traits.rs index acf4b0b7a..50e5a3e6e 100644 --- a/src/data_traits.rs +++ b/src/data_traits.rs @@ -14,6 +14,7 @@ use std::mem::{self, size_of}; use std::mem::MaybeUninit; use std::ptr::NonNull; use alloc::sync::Arc; +#[cfg(not(feature = "std"))] use alloc::vec::Vec; use crate::{ diff --git a/src/dimension/axes.rs b/src/dimension/axes.rs index fb1ff0995..5660675b5 100644 --- a/src/dimension/axes.rs +++ b/src/dimension/axes.rs @@ -143,7 +143,6 @@ where trait IncOps: Copy { fn post_inc(&mut self) -> Self; - fn post_dec(&mut self) -> Self; fn pre_dec(&mut self) -> Self; } @@ -155,12 +154,6 @@ impl IncOps for usize { x } #[inline(always)] - fn post_dec(&mut self) -> Self { - let x = *self; - *self -= 1; - x - } - #[inline(always)] fn pre_dec(&mut self) -> Self { *self -= 1; *self diff --git a/src/dimension/conversion.rs b/src/dimension/conversion.rs index 6b53a4eef..f6c408a75 100644 --- a/src/dimension/conversion.rs +++ b/src/dimension/conversion.rs @@ -10,6 +10,7 @@ use num_traits::Zero; use std::ops::{Index, IndexMut}; +#[cfg(not(feature = "std"))] use alloc::vec::Vec; use crate::{Dim, Dimension, Ix, Ix1, IxDyn, IxDynImpl}; diff --git a/src/dimension/dimension_trait.rs b/src/dimension/dimension_trait.rs index 7a3955fb7..14ec2cd31 100644 --- a/src/dimension/dimension_trait.rs +++ b/src/dimension/dimension_trait.rs @@ -9,6 +9,7 @@ use std::fmt::Debug; use std::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign}; use std::ops::{Index, IndexMut}; +#[cfg(not(feature = "std"))] use alloc::vec::Vec; use super::axes_of; diff --git a/src/dimension/dynindeximpl.rs b/src/dimension/dynindeximpl.rs index e81bf4f3d..c2aea032e 100644 --- a/src/dimension/dynindeximpl.rs +++ b/src/dimension/dynindeximpl.rs @@ -2,7 +2,9 @@ use crate::imp_prelude::*; use std::hash::{Hash, Hasher}; use std::ops::{Deref, DerefMut, Index, IndexMut}; use alloc::vec; +#[cfg(not(feature = "std"))] use alloc::boxed::Box; +#[cfg(not(feature = "std"))] use alloc::vec::Vec; const CAP: usize = 4; diff --git a/src/extension/nonnull.rs b/src/extension/nonnull.rs index 5aa50fdc2..4deee11ac 100644 --- a/src/extension/nonnull.rs +++ b/src/extension/nonnull.rs @@ -1,4 +1,5 @@ use std::ptr::NonNull; +#[cfg(not(feature = "std"))] use alloc::vec::Vec; /// Return a NonNull pointer to the vector's data diff --git a/src/free_functions.rs b/src/free_functions.rs index 156eee6b9..e9c3abff6 100644 --- a/src/free_functions.rs +++ b/src/free_functions.rs @@ -7,6 +7,7 @@ // except according to those terms. use alloc::vec; +#[cfg(not(feature = "std"))] use alloc::vec::Vec; use std::mem::{forget, size_of}; diff --git a/src/impl_1d.rs b/src/impl_1d.rs index 17f7729d6..a9fe84407 100644 --- a/src/impl_1d.rs +++ b/src/impl_1d.rs @@ -7,6 +7,7 @@ // except according to those terms. //! Methods for one-dimensional arrays. +#[cfg(not(feature = "std"))] use alloc::vec::Vec; use std::mem::MaybeUninit; diff --git a/src/impl_constructors.rs b/src/impl_constructors.rs index 049384ceb..2779e27d0 100644 --- a/src/impl_constructors.rs +++ b/src/impl_constructors.rs @@ -17,6 +17,7 @@ use num_traits::{One, Zero}; use std::mem; use std::mem::MaybeUninit; use alloc::vec; +#[cfg(not(feature = "std"))] use alloc::vec::Vec; use crate::dimension; diff --git a/src/impl_methods.rs b/src/impl_methods.rs index 0b6d0b2e1..19249f9e7 100644 --- a/src/impl_methods.rs +++ b/src/impl_methods.rs @@ -9,6 +9,7 @@ use std::mem::{size_of, ManuallyDrop}; use alloc::slice; use alloc::vec; +#[cfg(not(feature = "std"))] use alloc::vec::Vec; use rawpointer::PointerExt; diff --git a/src/impl_ops.rs b/src/impl_ops.rs index a267198ba..9eacd6b69 100644 --- a/src/impl_ops.rs +++ b/src/impl_ops.rs @@ -288,7 +288,6 @@ mod arithmetic_ops { use super::*; use crate::imp_prelude::*; - use num_complex::Complex; use std::ops::*; fn clone_opf(f: impl Fn(A, B) -> C) -> impl FnMut(&A, &B) -> C { diff --git a/src/impl_owned_array.rs b/src/impl_owned_array.rs index 8cfb82b55..aaa9f30b5 100644 --- a/src/impl_owned_array.rs +++ b/src/impl_owned_array.rs @@ -1,4 +1,5 @@ +#[cfg(not(feature = "std"))] use alloc::vec::Vec; use std::mem; use std::mem::MaybeUninit; diff --git a/src/iterators/mod.rs b/src/iterators/mod.rs index 063b22053..6bac471bd 100644 --- a/src/iterators/mod.rs +++ b/src/iterators/mod.rs @@ -17,6 +17,7 @@ mod windows; use std::iter::FromIterator; use std::marker::PhantomData; use std::ptr; +#[cfg(not(feature = "std"))] use alloc::vec::Vec; use crate::Ix1; diff --git a/src/linalg/impl_linalg.rs b/src/linalg/impl_linalg.rs index 52a15f44e..6a4542edd 100644 --- a/src/linalg/impl_linalg.rs +++ b/src/linalg/impl_linalg.rs @@ -16,6 +16,7 @@ use crate::{LinalgScalar, Zip}; use std::any::TypeId; use std::mem::MaybeUninit; +#[cfg(not(feature = "std"))] use alloc::vec::Vec; use num_complex::Complex; diff --git a/src/numeric/impl_numeric.rs b/src/numeric/impl_numeric.rs index afcd7e896..0a720cb3e 100644 --- a/src/numeric/impl_numeric.rs +++ b/src/numeric/impl_numeric.rs @@ -8,7 +8,7 @@ #[cfg(feature = "std")] use num_traits::Float; -use num_traits::{self, FromPrimitive, Zero}; +use num_traits::{FromPrimitive, Zero}; use std::ops::{Add, Div, Mul}; use crate::imp_prelude::*; diff --git a/src/slice.rs b/src/slice.rs index 0146d6dba..182d3723c 100644 --- a/src/slice.rs +++ b/src/slice.rs @@ -8,6 +8,7 @@ use crate::dimension::slices_intersect; use crate::error::{ErrorKind, ShapeError}; use crate::{ArrayViewMut, DimAdd, Dimension, Ix0, Ix1, Ix2, Ix3, Ix4, Ix5, Ix6, IxDyn}; +#[cfg(not(feature = "std"))] use alloc::vec::Vec; use std::convert::TryFrom; use std::fmt; diff --git a/src/split_at.rs b/src/split_at.rs index b05e58346..50466afdf 100644 --- a/src/split_at.rs +++ b/src/split_at.rs @@ -7,6 +7,7 @@ pub(crate) trait SplitAt { } pub(crate) trait SplitPreference : SplitAt { + #[allow(dead_code)] // used only when Rayon support is enabled fn can_split(&self) -> bool; fn split_preference(&self) -> (Axis, usize); fn split(self) -> (Self, Self) where Self: Sized { diff --git a/src/stacking.rs b/src/stacking.rs index 5a47589d5..16058f39d 100644 --- a/src/stacking.rs +++ b/src/stacking.rs @@ -6,6 +6,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[cfg(not(feature = "std"))] use alloc::vec::Vec; use crate::dimension; diff --git a/tests/iterators.rs b/tests/iterators.rs index d7f7c5823..addd59adc 100644 --- a/tests/iterators.rs +++ b/tests/iterators.rs @@ -6,7 +6,7 @@ )] use ndarray::prelude::*; -use ndarray::{arr3, aview1, indices, s, Axis, Slice, Zip}; +use ndarray::{arr3, indices, s, Slice, Zip}; use itertools::assert_equal; use itertools::enumerate; From b02ae59f6aefaa06db87c2625453dc7ce425687c Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Mon, 26 Feb 2024 20:20:03 +0100 Subject: [PATCH 2/2] dimension: Fix contig check for single element arrays When an array has 0 or 1 elements, strides don't matter anymore. The general case of this function handled this correctly, but the special case for ndim == 1 did not. --- src/dimension/dimension_trait.rs | 30 +++++++++++++++++------------- tests/array.rs | 16 ++++++++++++++++ 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/dimension/dimension_trait.rs b/src/dimension/dimension_trait.rs index 14ec2cd31..c594859e9 100644 --- a/src/dimension/dimension_trait.rs +++ b/src/dimension/dimension_trait.rs @@ -285,21 +285,25 @@ pub trait Dimension: return true; } if dim.ndim() == 1 { - return strides[0] as isize == -1; - } - let order = strides._fastest_varying_stride_order(); - let strides = strides.slice(); - - let dim_slice = dim.slice(); - let mut cstride = 1; - for &i in order.slice() { - // a dimension of length 1 can have unequal strides - if dim_slice[i] != 1 && (strides[i] as isize).unsigned_abs() != cstride { - return false; + // fast case for ndim == 1: + // Either we have length <= 1, then stride is arbitrary, + // or we have stride == 1 or stride == -1, but +1 case is already handled above. + dim[0] <= 1 || strides[0] as isize == -1 + } else { + let order = strides._fastest_varying_stride_order(); + let strides = strides.slice(); + + let dim_slice = dim.slice(); + let mut cstride = 1; + for &i in order.slice() { + // a dimension of length 1 can have unequal strides + if dim_slice[i] != 1 && (strides[i] as isize).unsigned_abs() != cstride { + return false; + } + cstride *= dim_slice[i]; } - cstride *= dim_slice[i]; + true } - true } /// Return the axis ordering corresponding to the fastest variation diff --git a/tests/array.rs b/tests/array.rs index 8fdbb9992..d770d7822 100644 --- a/tests/array.rs +++ b/tests/array.rs @@ -1957,6 +1957,22 @@ fn test_contiguous() { assert!(b.as_slice_memory_order().is_some()); } +#[test] +fn test_contiguous_single_element() +{ + assert_matches!(array![1].as_slice_memory_order(), Some(&[1])); + + let arr1 = array![1, 2, 3]; + assert_matches!(arr1.slice(s![0..1]).as_slice_memory_order(), Some(&[1])); + assert_matches!(arr1.slice(s![1..2]).as_slice_memory_order(), Some(&[2])); + assert_matches!(arr1.slice(s![2..3]).as_slice_memory_order(), Some(&[3])); + assert_matches!(arr1.slice(s![0..0]).as_slice_memory_order(), Some(&[])); + + let arr2 = array![[1, 2, 3], [4, 5, 6]]; + assert_matches!(arr2.slice(s![.., 2..3]).as_slice_memory_order(), None); + assert_matches!(arr2.slice(s![1, 2..3]).as_slice_memory_order(), Some(&[6])); +} + #[test] fn test_contiguous_neg_strides() { let s = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];