From 40772fea15a31dddfa721be871af2185a99a1947 Mon Sep 17 00:00:00 2001 From: Wind Date: Thu, 30 May 2024 21:29:46 +0800 Subject: [PATCH] fix do closure with both required, options, and rest args (#13002) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description Fixes: #12985 `val_iter` has already handle required positional and optional positional arguments, it not skip them again while handling rest arguments. # User-Facing Changes Makes `do {|a, ...b| echo $a ...$b} 1 2 3 4` output the following again: ```nushell ╭───┬───╮ │ 0 │ 1 │ │ 1 │ 2 │ │ 2 │ 3 │ │ 3 │ 4 │ ╰───┴───╯ ``` # Tests + Formatting Added some test cases --- crates/nu-cmd-lang/src/core_commands/do_.rs | 4 +--- tests/shell/pipeline/commands/internal.rs | 9 +++++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/crates/nu-cmd-lang/src/core_commands/do_.rs b/crates/nu-cmd-lang/src/core_commands/do_.rs index 5f14e88c07..8ca3fbac56 100644 --- a/crates/nu-cmd-lang/src/core_commands/do_.rs +++ b/crates/nu-cmd-lang/src/core_commands/do_.rs @@ -298,9 +298,7 @@ fn bind_args_to( if let Some(rest_positional) = &signature.rest_positional { let mut rest_items = vec![]; - for result in - val_iter.skip(signature.required_positional.len() + signature.optional_positional.len()) - { + for result in val_iter { rest_items.push(result); } diff --git a/tests/shell/pipeline/commands/internal.rs b/tests/shell/pipeline/commands/internal.rs index 67d4ee31a9..98f3fb88c9 100644 --- a/tests/shell/pipeline/commands/internal.rs +++ b/tests/shell/pipeline/commands/internal.rs @@ -539,6 +539,15 @@ fn dynamic_closure_optional_arg() { fn dynamic_closure_rest_args() { let actual = nu!(r#"let closure = {|...args| $args | str join ""}; do $closure 1 2 3"#); assert_eq!(actual.out, "123"); + + let actual = nu!( + r#"let closure = {|required, ...args| $"($required), ($args | str join "")"}; do $closure 1 2 3"# + ); + assert_eq!(actual.out, "1, 23"); + let actual = nu!( + r#"let closure = {|required, optional?, ...args| $"($required), ($optional), ($args | str join "")"}; do $closure 1 2 3"# + ); + assert_eq!(actual.out, "1, 2, 3"); } #[cfg(feature = "which-support")]