diff --git a/crates/nu-parser/src/parser.rs b/crates/nu-parser/src/parser.rs index 288ad4e2b3..ef1955c6e4 100644 --- a/crates/nu-parser/src/parser.rs +++ b/crates/nu-parser/src/parser.rs @@ -1700,16 +1700,18 @@ pub fn parse_brace_expr( parse_closure_expression(working_set, shape, span) } else if matches!(third_token, Some(b":")) { parse_full_cell_path(working_set, None, 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'(') - }) { - parse_record(working_set, span) - } else if matches!(shape, SyntaxShape::Closure(_)) || matches!(shape, SyntaxShape::Any) { + } 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'(') + }) { + parse_record(working_set, span) + } else if matches!(shape, SyntaxShape::Any) { + parse_closure_expression(working_set, shape, span) } else { working_set.error(ParseError::ExpectedWithStringMsg( format!("non-block value: {shape}"), diff --git a/src/tests/test_spread.rs b/src/tests/test_spread.rs index 31a6183b1a..f031c91988 100644 --- a/src/tests/test_spread.rs +++ b/src/tests/test_spread.rs @@ -190,3 +190,15 @@ fn deprecate_implicit_spread_for_externals() { .contains("Automatically spreading lists is deprecated")); assert_eq!(result.out, "1 2"); } + +#[test] +fn respect_shape() -> TestResult { + fail_test( + "def foo [...rest] { ...$rest }; foo bar baz", + "executable was not found", + ) + .unwrap(); + fail_test("module foo { ...$bar }", "expected_keyword").unwrap(); + run_test(r#"def "...$foo" [] {2}; do { ...$foo }"#, "2").unwrap(); + run_test(r#"match "...$foo" { ...$foo => 5 }"#, "5") +}