diff --git a/crates/nu-command/src/filters/last.rs b/crates/nu-command/src/filters/last.rs index 4b4c8e140..969846c60 100644 --- a/crates/nu-command/src/filters/last.rs +++ b/crates/nu-command/src/filters/last.rs @@ -77,14 +77,18 @@ impl Command for Last { let span = call.head; let rows: Option = call.opt(engine_state, stack, 0)?; - let to_keep = rows.unwrap_or(1).try_into().unwrap_or(0); - - // early exit for `last 0` - if to_keep == 0 { - return Ok(Vec::::new() - .into_pipeline_data(engine_state.ctrlc.clone()) - .set_metadata(metadata)); - } + let to_keep = match rows.unwrap_or(1) { + 0 => { + // early exit for `last 0` + return Ok(Vec::::new() + .into_pipeline_data(engine_state.ctrlc.clone()) + .set_metadata(metadata)); + } + i if i < 0 => { + return Err(ShellError::NeedsPositiveValue(span)); + } + i => i as usize, + }; // only keep last `to_keep` rows in memory let mut buf = VecDeque::<_>::new(); diff --git a/crates/nu-command/tests/commands/last.rs b/crates/nu-command/tests/commands/last.rs index ba0baae99..92c7fc888 100644 --- a/crates/nu-command/tests/commands/last.rs +++ b/crates/nu-command/tests/commands/last.rs @@ -78,3 +78,16 @@ fn gets_last_row_as_list_when_amount_given() { assert_eq!(actual.out, "list"); } + +#[test] +fn last_errors_on_negative_index() { + let actual = nu!( + cwd: ".", pipeline( + r#" + [1, 2, 3] + | last -2 + "# + )); + + assert!(actual.err.contains("use a positive value")); +}