From 04956be1b7f0b5ba21c6eabf2048ebb199a3e53c Mon Sep 17 00:00:00 2001 From: Benjamin Lucier Date: Tue, 10 Nov 2026 18:23:28 -0500 Subject: [PATCH] fix: explain invalid `s![]` arguments in the compiler error Wrapping the arguments of `s![]` in brackets, e.g. `s![[1..3, ..]]`, produced "the trait `SliceNextDim` is not implemented for `[Range<{integer}>; 2]`", which does not mention the macro or what it expects. Add `#[diagnostic::on_unimplemented]` to `SliceNextDim` so the error says which argument types `s![]` accepts and that the arguments should not be wrapped in brackets or parentheses. Also document the mistake in the `s![]` docs with a `compile_fail` example. Closes #1122 Co-Authored-By: Claude Opus 5.5 --- src/slice.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/slice.rs b/src/slice.rs index e2ce1e727..23bce4bb0 100644 --- a/src/slice.rs +++ b/src/slice.rs @@ -672,6 +672,13 @@ where /// Trait for determining dimensionality of input and output for [`s!`] macro. #[doc(hidden)] +#[diagnostic::on_unimplemented( + message = "`{Self}` cannot be used as an argument to the `s![]` macro", + label = "not an index, range, `Slice`, or `NewAxis`", + note = "each comma-separated argument to `s![]` must be an index (`isize`, `usize` or `i32`), a range \ + such as `1..3` or `..`, a `Slice`, or `NewAxis`, optionally followed by `;step`", + note = "do not wrap the arguments in brackets or parentheses: write `s![1..3, ..]`, not `s![[1..3, ..]]`" +)] pub trait SliceNextDim { /// Number of dimensions that this slicing argument consumes in the input array. @@ -746,6 +753,17 @@ impl_slicenextdim!((), NewAxis, Ix0, Ix1); /// `RangeFull` where `I` is `isize`, `usize`, or `i32`. *step* must be a type /// that can be converted to `isize` with the `as` keyword. /// +/// The square brackets belong to the macro invocation, so the elements are +/// written directly inside them, not wrapped in an array or tuple: +/// `s![[1..3, ..]]` does not compile, so write `s![1..3, ..]` instead. +/// +/// ```compile_fail,E0277 +/// use ndarray::{s, Array2}; +/// +/// let a = Array2::::zeros((4, 4)); +/// let _ = a.slice(s![[1..3, 0..2]]); +/// ``` +/// /// For example, `s![0..4;2, 6, 1..5, NewAxis]` is a slice of the first axis /// for 0..4 with step size 2, a subview of the second axis at index 6, a slice /// of the third axis for 1..5 with default step size 1, and a new axis of