diff --git a/ndc_stdlib/src/sequence.rs b/ndc_stdlib/src/sequence.rs index 7a1069eb..ea6c7f8d 100644 --- a/ndc_stdlib/src/sequence.rs +++ b/ndc_stdlib/src/sequence.rs @@ -707,8 +707,10 @@ mod inner { /// Returns a list of all contiguous windows of `length` size. The windows overlap. If the `seq` is shorter than size, the iterator returns no values. #[function(return_type = Vec<_>)] - pub fn windows(seq: SeqValue, length: i64) -> anyhow::Result { - let length = length as usize; + pub fn windows(seq: SeqValue, length: usize) -> anyhow::Result { + if length == 0 { + return Err(anyhow!("window size must be non-zero")); + } Ok(Value::list( seq.try_into_iter() .ok_or_else(|| anyhow!("windows requires a sequence"))? diff --git a/tests/functional/programs/900_bugs/bug0024_windows_zero_size.ndc b/tests/functional/programs/900_bugs/bug0024_windows_zero_size.ndc new file mode 100644 index 00000000..372e5172 --- /dev/null +++ b/tests/functional/programs/900_bugs/bug0024_windows_zero_size.ndc @@ -0,0 +1,5 @@ +// `windows(seq, 0)` used to reach `slice::windows(0)`, which panics with +// "window size must be non-zero". It now returns a graceful error, matching +// the sibling `chunks` function. +// expect-error: window size must be non-zero +windows([1, 2, 3], 0);