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:
JT
2023-03-24 22:50:23 +13:00
committed by GitHub
parent 85bfdba1e2
commit 8d5fbc6fcb
8 changed files with 30 additions and 6 deletions

View File

@ -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);
}