mirror of
https://github.com/nushell/nushell
synced 2024-11-10 15:14:14 +00:00
Fix closures that use matches. Move 'collect' to core. (#8596)
# Description Fix patterns in pattern matching to properly declare their variables when discovering which variables need to be closed over when creating a closure. Also, moves `collect` to core, so that the core language can use `$in`. Fixes #8595 # User-Facing Changes See above # Tests + Formatting Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass > **Note** > from `nushell` you can also use the `toolkit` as follows > ```bash > use toolkit.nu # or use an `env_change` hook to activate it automatically > toolkit check pr > ``` # After Submitting If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date.
This commit is contained in:
parent
85bfdba1e2
commit
8d5fbc6fcb
8 changed files with 30 additions and 6 deletions
|
@ -111,6 +111,11 @@ impl Command for Match {
|
|||
example: "match [1, 2, 3] { [$a, $b, $c] => { $a + $b + $c }, _ => 0 }",
|
||||
result: Some(Value::test_int(6)),
|
||||
},
|
||||
Example {
|
||||
description: "Match against pipeline input",
|
||||
example: "{a: {b: 3}} | match $in.a { { $b } => ($b + 10) }",
|
||||
result: Some(Value::test_int(13)),
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
mod alias;
|
||||
mod break_;
|
||||
mod collect;
|
||||
mod commandline;
|
||||
mod const_;
|
||||
mod continue_;
|
||||
|
@ -41,6 +42,7 @@ mod while_;
|
|||
|
||||
pub use alias::Alias;
|
||||
pub use break_::Break;
|
||||
pub use collect::Collect;
|
||||
pub use commandline::Commandline;
|
||||
pub use const_::Const;
|
||||
pub use continue_::Continue;
|
||||
|
|
|
@ -18,6 +18,7 @@ pub fn create_default_context() -> EngineState {
|
|||
bind_command! {
|
||||
Alias,
|
||||
Break,
|
||||
Collect,
|
||||
Commandline,
|
||||
Const,
|
||||
Continue,
|
||||
|
|
|
@ -13,7 +13,7 @@ mod test_examples {
|
|||
check_example_evaluates_to_expected_output,
|
||||
check_example_input_and_output_types_match_command_signature,
|
||||
};
|
||||
use crate::{Break, Describe, Mut};
|
||||
use crate::{Break, Collect, Describe, Mut};
|
||||
use crate::{Echo, If, Let};
|
||||
use nu_protocol::{
|
||||
engine::{Command, EngineState, StateWorkingSet},
|
||||
|
@ -66,6 +66,7 @@ mod test_examples {
|
|||
working_set.add_decl(Box::new(If));
|
||||
working_set.add_decl(Box::new(Let));
|
||||
working_set.add_decl(Box::new(Mut));
|
||||
working_set.add_decl(Box::new(Collect));
|
||||
|
||||
// Adding the command that is being tested to the working set
|
||||
working_set.add_decl(cmd);
|
||||
|
|
|
@ -36,7 +36,6 @@ pub fn create_default_context() -> EngineState {
|
|||
All,
|
||||
Any,
|
||||
Append,
|
||||
Collect,
|
||||
Columns,
|
||||
Compact,
|
||||
Default,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
mod all;
|
||||
mod any;
|
||||
mod append;
|
||||
mod collect;
|
||||
mod columns;
|
||||
mod compact;
|
||||
mod default;
|
||||
|
@ -58,7 +57,6 @@ mod zip;
|
|||
pub use all::All;
|
||||
pub use any::Any;
|
||||
pub use append::Append;
|
||||
pub use collect::Collect;
|
||||
pub use columns::Columns;
|
||||
pub use compact::Compact;
|
||||
pub use default::Default;
|
||||
|
|
|
@ -11,8 +11,8 @@ use crate::{
|
|||
use nu_protocol::{
|
||||
ast::{
|
||||
Argument, Assignment, Bits, Block, Boolean, Call, CellPath, Comparison, Expr, Expression,
|
||||
FullCellPath, ImportPattern, ImportPatternHead, ImportPatternMember, Math, Operator,
|
||||
PathMember, Pipeline, PipelineElement, RangeInclusion, RangeOperator,
|
||||
FullCellPath, ImportPattern, ImportPatternHead, ImportPatternMember, MatchPattern, Math,
|
||||
Operator, PathMember, Pattern, Pipeline, PipelineElement, RangeInclusion, RangeOperator,
|
||||
},
|
||||
engine::StateWorkingSet,
|
||||
span, BlockId, Flag, PositionalArg, Signature, Span, Spanned, SyntaxShape, Type, Unit, VarId,
|
||||
|
@ -6005,6 +6005,23 @@ pub fn discover_captures_in_pipeline_element(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn discover_captures_in_pattern(pattern: &MatchPattern, seen: &mut Vec<VarId>) {
|
||||
match &pattern.pattern {
|
||||
Pattern::Variable(var_id) => seen.push(*var_id),
|
||||
Pattern::List(items) => {
|
||||
for item in items {
|
||||
discover_captures_in_pattern(item, seen)
|
||||
}
|
||||
}
|
||||
Pattern::Record(items) => {
|
||||
for item in items {
|
||||
discover_captures_in_pattern(&item.1, seen)
|
||||
}
|
||||
}
|
||||
Pattern::Value(_) | Pattern::IgnoreValue | Pattern::Garbage => {}
|
||||
}
|
||||
}
|
||||
|
||||
// Closes over captured variables
|
||||
pub fn discover_captures_in_expr(
|
||||
working_set: &StateWorkingSet,
|
||||
|
@ -6206,6 +6223,7 @@ pub fn discover_captures_in_expr(
|
|||
Expr::MatchPattern(_) => {}
|
||||
Expr::MatchBlock(match_block) => {
|
||||
for match_ in match_block {
|
||||
discover_captures_in_pattern(&match_.0, seen);
|
||||
let result = discover_captures_in_expr(working_set, &match_.1, seen, seen_blocks)?;
|
||||
output.extend(&result);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue