From 0491803bc798049d0170bf0233b161db9eb0f3f8 Mon Sep 17 00:00:00 2001 From: luismeyer95 Date: Fri, 2 May 2025 14:44:01 +0200 Subject: [PATCH] fix(parser): don't parse closure in block position --- crates/nu-parser/src/parser.rs | 8 ++++---- crates/nu-parser/tests/test_parser.rs | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/crates/nu-parser/src/parser.rs b/crates/nu-parser/src/parser.rs index 06a38afe7e..c067dff62d 100644 --- a/crates/nu-parser/src/parser.rs +++ b/crates/nu-parser/src/parser.rs @@ -2034,6 +2034,10 @@ pub fn parse_brace_expr( } else { parse_record(working_set, span) } + } else if matches!(shape, SyntaxShape::Block) { + parse_block_expression(working_set, span) + } else if matches!(shape, SyntaxShape::MatchBlock) { + parse_match_block_expression(working_set, span) } else if matches!(second_token_contents, Some(TokenContents::Pipe)) || matches!(second_token_contents, Some(TokenContents::PipePipe)) { @@ -2042,10 +2046,6 @@ pub fn parse_brace_expr( parse_full_cell_path(working_set, None, span) } else if matches!(shape, SyntaxShape::Closure(_)) { parse_closure_expression(working_set, shape, span) - } else if matches!(shape, SyntaxShape::Block) { - parse_block_expression(working_set, span) - } else if matches!(shape, SyntaxShape::MatchBlock) { - parse_match_block_expression(working_set, span) } else if second_token.is_some_and(|c| { c.len() > 3 && c.starts_with(b"...") && (c[3] == b'$' || c[3] == b'{' || c[3] == b'(') }) { diff --git a/crates/nu-parser/tests/test_parser.rs b/crates/nu-parser/tests/test_parser.rs index 945190014e..43e81df9ff 100644 --- a/crates/nu-parser/tests/test_parser.rs +++ b/crates/nu-parser/tests/test_parser.rs @@ -2724,6 +2724,23 @@ mod input_types { } } + #[test] + fn closure_in_block_position_errors_correctly() { + let mut engine_state = EngineState::new(); + add_declarations(&mut engine_state); + + let mut working_set = StateWorkingSet::new(&engine_state); + let inputs = [ + r#"if true { || print hi }"#, + r#"match true { || print hi }"#, + ]; + + for input in inputs { + parse(&mut working_set, None, input.as_bytes(), true); + assert!(!working_set.parse_errors.is_empty(), "testing: {input}"); + } + } + #[test] fn else_errors_correctly() { let mut engine_state = EngineState::new();