Skip to content

Commit

Permalink
Simplify features and make documentation call out feature gates (#1479)
Browse files Browse the repository at this point in the history
* Makes use of the nightly `doc_cfg` feature to automatically mark feature-gated items as requiring that feature.

This is possible thanks to the fact that docs.rs runs on nightly. While this may not be stabilized (and therefore may eventually reverse), I think it's extremely useful to users and only requires small additional configurations that would be easy to remove in the future.

* Adds appropriate arguments to CI/CD and removes serde-1, test, and docs features

* Fixes clippy complaining about `return None` instead of question marks
  • Loading branch information
akern40 authored Feb 3, 2025
1 parent d5f32ec commit c7391e9
Show file tree
Hide file tree
Showing 14 changed files with 39 additions and 29 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ name: Continuous integration
env:
CARGO_TERM_COLOR: always
HOST: x86_64-unknown-linux-gnu
FEATURES: "test docs"
FEATURES: "approx,serde,rayon"
RUSTFLAGS: "-D warnings"
MSRV: 1.64.0
BLAS_MSRV: 1.71.1
Expand All @@ -30,7 +30,7 @@ jobs:
toolchain: ${{ matrix.rust }}
components: clippy
- uses: Swatinem/rust-cache@v2
- run: cargo clippy --features docs
- run: cargo clippy --features approx,serde,rayon

format:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -139,7 +139,7 @@ jobs:
- uses: Swatinem/rust-cache@v2
- name: Install cross
run: cargo install cross
- run: ./scripts/cross-tests.sh "docs" ${{ matrix.rust }} ${{ matrix.target }}
- run: ./scripts/cross-tests.sh "approx,serde,rayon" ${{ matrix.rust }} ${{ matrix.target }}

cargo-careful:
#if: ${{ github.event_name == 'merge_group' }}
Expand All @@ -161,10 +161,10 @@ jobs:
strategy:
matrix:
rust:
- stable
- nightly # This is what docs.rs runs on, and is needed for the feature flags
name: docs/${{ matrix.rust }}
env:
RUSTDOCFLAGS: "-Dwarnings"
RUSTDOCFLAGS: "-Dwarnings --cfg docsrs"
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@master
Expand Down
13 changes: 4 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,6 @@ default = ["std"]
blas = ["dep:cblas-sys", "dep:libc"]

serde = ["dep:serde"]
# Old name for the serde feature
serde-1 = ["dep:serde"]

# These features are used for testing
test = []

# This feature is used for docs
docs = ["approx", "serde", "rayon"]

std = ["num-traits/std", "matrixmultiply/std"]
rayon = ["dep:rayon", "std"]
Expand Down Expand Up @@ -121,5 +113,8 @@ opt-level = 2
no-dev-version = true
tag-name = "{{version}}"

# Config specific to docs.rs
[package.metadata.docs.rs]
features = ["docs"]
features = ["approx", "serde", "rayon"]
# Define the configuration attribute `docsrs`
rustdoc-args = ["--cfg", "docsrs"]
6 changes: 2 additions & 4 deletions src/array_approx.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#[cfg(feature = "approx")]
#[cfg_attr(docsrs, doc(cfg(feature = "approx")))]
mod approx_methods
{
use crate::imp_prelude::*;
Expand All @@ -10,8 +11,6 @@ mod approx_methods
{
/// A test for equality that uses the elementwise absolute difference to compute the
/// approximate equality of two arrays.
///
/// **Requires crate feature `"approx"`**
pub fn abs_diff_eq<S2>(&self, other: &ArrayBase<S2, D>, epsilon: A::Epsilon) -> bool
where
A: ::approx::AbsDiffEq<S2::Elem>,
Expand All @@ -23,8 +22,6 @@ mod approx_methods

/// A test for equality that uses an elementwise relative comparison if the values are far
/// apart; and the absolute difference otherwise.
///
/// **Requires crate feature `"approx"`**
pub fn relative_eq<S2>(&self, other: &ArrayBase<S2, D>, epsilon: A::Epsilon, max_relative: A::Epsilon) -> bool
where
A: ::approx::RelativeEq<S2::Elem>,
Expand Down Expand Up @@ -192,4 +189,5 @@ macro_rules! impl_approx_traits {
}

#[cfg(feature = "approx")]
#[cfg_attr(docsrs, doc(cfg(feature = "approx")))]
impl_approx_traits!(approx, "**Requires crate feature `\"approx\"`.**");
1 change: 1 addition & 0 deletions src/arraytraits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ where
}

#[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
// Use version number so we can add a packed format later.
pub const ARRAY_FORMAT_VERSION: u8 = 1u8;

Expand Down
1 change: 1 addition & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ impl PartialEq for ShapeError
}

#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl Error for ShapeError {}

impl fmt::Display for ShapeError
Expand Down
4 changes: 4 additions & 0 deletions src/impl_constructors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ where S: DataOwned<Elem = A>
/// assert!(array == arr1(&[0.0, 0.25, 0.5, 0.75, 1.0]))
/// ```
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub fn linspace(start: A, end: A, n: usize) -> Self
where A: Float
{
Expand All @@ -117,6 +118,7 @@ where S: DataOwned<Elem = A>
/// assert!(array == arr1(&[0., 1., 2., 3., 4.]))
/// ```
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub fn range(start: A, end: A, step: A) -> Self
where A: Float
{
Expand Down Expand Up @@ -145,6 +147,7 @@ where S: DataOwned<Elem = A>
/// # }
/// ```
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub fn logspace(base: A, start: A, end: A, n: usize) -> Self
where A: Float
{
Expand Down Expand Up @@ -179,6 +182,7 @@ where S: DataOwned<Elem = A>
/// # example().unwrap();
/// ```
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub fn geomspace(start: A, end: A, n: usize) -> Option<Self>
where A: Float
{
Expand Down
5 changes: 1 addition & 4 deletions src/impl_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2299,10 +2299,7 @@ where
let dim = dim.into_dimension();

// Note: zero strides are safe precisely because we return an read-only view
let broadcast_strides = match upcast(&dim, &self.dim, &self.strides) {
Some(st) => st,
None => return None,
};
let broadcast_strides = upcast(&dim, &self.dim, &self.strides)?;
unsafe { Some(ArrayView::new(self.ptr, dim, broadcast_strides)) }
}

Expand Down
5 changes: 1 addition & 4 deletions src/iterators/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,7 @@ impl<A> DoubleEndedIterator for Baseiter<A, Ix1>
#[inline]
fn next_back(&mut self) -> Option<Self::Item>
{
let index = match self.index {
None => return None,
Some(ix) => ix,
};
let index = self.index?;
self.dim[0] -= 1;
let offset = Ix1::stride_offset(&self.dim, &self.strides);
if index == self.dim {
Expand Down
8 changes: 7 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#![doc(test(attr(allow(unused_variables))))]
#![doc(test(attr(allow(deprecated))))]
#![cfg_attr(not(feature = "std"), no_std)]
// Enable the doc_cfg nightly feature for including feature gate flags in the documentation
#![cfg_attr(docsrs, feature(doc_cfg))]

//! The `ndarray` crate provides an *n*-dimensional container for general elements
//! and for numerics.
Expand Down Expand Up @@ -120,7 +122,7 @@ extern crate std;
#[cfg(feature = "blas")]
extern crate cblas_sys;

#[cfg(feature = "docs")]
#[cfg(docsrs)]
pub mod doc;

#[cfg(target_has_atomic = "ptr")]
Expand Down Expand Up @@ -148,6 +150,7 @@ use crate::iterators::{ElementsBase, ElementsBaseMut, Iter, IterMut};
pub use crate::arraytraits::AsArray;
pub use crate::linalg_traits::LinalgScalar;
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub use crate::linalg_traits::NdFloat;

pub use crate::stacking::{concatenate, stack};
Expand Down Expand Up @@ -189,9 +192,11 @@ mod layout;
mod linalg_traits;
mod linspace;
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub use crate::linspace::{linspace, range, Linspace};
mod logspace;
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub use crate::logspace::{logspace, Logspace};
mod math_cell;
mod numeric_util;
Expand Down Expand Up @@ -1587,6 +1592,7 @@ where

// parallel methods
#[cfg(feature = "rayon")]
#[cfg_attr(docsrs, doc(cfg(feature = "rayon")))]
pub mod parallel;

mod impl_1d;
Expand Down
5 changes: 5 additions & 0 deletions src/linalg_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ impl<T> LinalgScalar for T where T: 'static + Copy + Zero + One + Add<Output = T
/// operations (`ScalarOperand`).
///
/// This trait can only be implemented by `f32` and `f64`.
///
/// **Requires default crate feature `"std"`**
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub trait NdFloat:
Float
+ AddAssign
Expand All @@ -59,6 +62,8 @@ pub trait NdFloat:
}

#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl NdFloat for f32 {}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl NdFloat for f64 {}
1 change: 1 addition & 0 deletions src/numeric/impl_float_maths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ macro_rules! binary_ops {
///
/// Element-wise math functions for any array type that contains float number.
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl<A, S, D> ArrayBase<S, D>
where
A: 'static + Float,
Expand Down
4 changes: 4 additions & 0 deletions src/numeric/impl_numeric.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ where
/// ```
#[track_caller]
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub fn var(&self, ddof: A) -> A
where A: Float + FromPrimitive
{
Expand Down Expand Up @@ -205,6 +206,7 @@ where
/// ```
#[track_caller]
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub fn std(&self, ddof: A) -> A
where A: Float + FromPrimitive
{
Expand Down Expand Up @@ -361,6 +363,7 @@ where
/// ```
#[track_caller]
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub fn var_axis(&self, axis: Axis, ddof: A) -> Array<A, D::Smaller>
where
A: Float + FromPrimitive,
Expand Down Expand Up @@ -431,6 +434,7 @@ where
/// ```
#[track_caller]
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub fn std_axis(&self, axis: Axis, ddof: A) -> Array<A, D::Smaller>
where
A: Float + FromPrimitive,
Expand Down
2 changes: 0 additions & 2 deletions src/parallel/impl_par_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ use crate::parallel::prelude::*;
use crate::partial::Partial;

/// # Parallel methods
///
/// These methods require crate feature `rayon`.
impl<A, S, D> ArrayBase<S, D>
where
S: DataMut<Elem = A>,
Expand Down
3 changes: 3 additions & 0 deletions src/partial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ impl<T> Partial<T>
}

#[cfg(feature = "rayon")]
#[cfg_attr(docsrs, doc(cfg(feature = "rayon")))]
pub(crate) fn stub() -> Self
{
Self {
Expand All @@ -46,6 +47,7 @@ impl<T> Partial<T>
}

#[cfg(feature = "rayon")]
#[cfg_attr(docsrs, doc(cfg(feature = "rayon")))]
pub(crate) fn is_stub(&self) -> bool
{
self.ptr.is_null()
Expand All @@ -60,6 +62,7 @@ impl<T> Partial<T>
}

#[cfg(feature = "rayon")]
#[cfg_attr(docsrs, doc(cfg(feature = "rayon")))]
/// Merge if they are in order (left to right) and contiguous.
/// Skips merge if T does not need drop.
pub(crate) fn try_merge(mut left: Self, right: Self) -> Self
Expand Down

0 comments on commit c7391e9

Please sign in to comment.