Fix return in filter closure eval (#12292)

# Description
Closes https://github.com/nushell/nushell/issues/12257

This was down to the use of `eval_block` instead of
`eval_block_with_early_return`. We may want to reconsider how we
differentiate between this behavior. We currently need to check all the
remaining commands that can invoke a closure block, if they properly
handle `ShellError::Return` as a passing of a `Value`

- **Add test for `return` in `filter` closure**
- **Fix use of `return` in `filter` closure**

# User-Facing Changes
You can now return a value from a `filter` closure


# Tests + Formatting
Regression test
This commit is contained in:
Stefan Holderbach 2024-03-26 17:50:36 +01:00 committed by GitHub
parent b70766e6f5
commit 592dc4bbfa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 24 additions and 5 deletions

View File

@ -1,5 +1,5 @@
use super::utils::chain_error_with_input; use super::utils::chain_error_with_input;
use nu_engine::{get_eval_block, CallExt}; use nu_engine::{get_eval_block_with_early_return, CallExt};
use nu_protocol::ast::Call; use nu_protocol::ast::Call;
use nu_protocol::engine::{Closure, Command, EngineState, Stack}; use nu_protocol::engine::{Closure, Command, EngineState, Stack};
@ -62,7 +62,7 @@ a variable. On the other hand, the "row condition" syntax is not supported."#
let orig_env_vars = stack.env_vars.clone(); let orig_env_vars = stack.env_vars.clone();
let orig_env_hidden = stack.env_hidden.clone(); let orig_env_hidden = stack.env_hidden.clone();
let span = call.head; let span = call.head;
let eval_block = get_eval_block(&engine_state); let eval_block_with_early_return = get_eval_block_with_early_return(&engine_state);
match input { match input {
PipelineData::Empty => Ok(PipelineData::Empty), PipelineData::Empty => Ok(PipelineData::Empty),
@ -84,7 +84,7 @@ a variable. On the other hand, the "row condition" syntax is not supported."#
} }
} }
match eval_block( match eval_block_with_early_return(
&engine_state, &engine_state,
&mut stack, &mut stack,
&block, &block,
@ -126,7 +126,7 @@ a variable. On the other hand, the "row condition" syntax is not supported."#
} }
} }
match eval_block( match eval_block_with_early_return(
&engine_state, &engine_state,
&mut stack, &mut stack,
&block, &block,
@ -159,7 +159,7 @@ a variable. On the other hand, the "row condition" syntax is not supported."#
} }
} }
Ok(match eval_block( Ok(match eval_block_with_early_return(
&engine_state, &engine_state,
&mut stack, &mut stack,
&block, &block,

View File

@ -0,0 +1,18 @@
use nu_test_support::{nu, pipeline};
#[test]
fn filter_with_return_in_closure() {
let actual = nu!(pipeline(
"
1..10 | filter { |it|
if $it mod 2 == 0 {
return true
};
return false;
} | to nuon --raw
"
));
assert_eq!(actual.out, "[2, 4, 6, 8, 10]");
assert!(actual.err.is_empty());
}

View File

@ -30,6 +30,7 @@ mod every;
mod exec; mod exec;
mod export_def; mod export_def;
mod fill; mod fill;
mod filter;
mod find; mod find;
mod first; mod first;
mod flatten; mod flatten;